From badb2382a86dacfecf2793fa9edd85fa17497d37 Mon Sep 17 00:00:00 2001 From: Korey Sewell Date: Tue, 15 Sep 2009 01:44:48 -0400 Subject: 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 (limited to 'src') diff --git a/src/cpu/inorder/SConscript b/src/cpu/inorder/SConscript index 64f1b5481..82a1028c2 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 a2367db63..4107ac3b4 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 75d77c818..9fb8e0df4 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 5ee7b31db..a19137dd8 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 a6abb28b2..9f0927b2f 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 e95a6d039..a91c6a763 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 fe1a0faa1..8247bf1fb 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 327f8ac71..2489c525f 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 000000000..b3a54efb1 --- /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 9b3b39fcb..0571b6e04 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; -- cgit v1.2.3 From 9900ac95b5c0e197f03e5efd8d9f840a643b32c6 Mon Sep 17 00:00:00 2001 From: Vince Weaver Date: Tue, 15 Sep 2009 05:30:08 -0700 Subject: [mq]: x86syscalls.patch --- src/arch/x86/linux/syscalls.cc | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/arch/x86/linux/syscalls.cc b/src/arch/x86/linux/syscalls.cc index 4d7bca95c..5a425ed9a 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), -- cgit v1.2.3 From 0f569b4d9dd5b7be253d45c22e9c40f615e90ecd Mon Sep 17 00:00:00 2001 From: Vince Weaver Date: Tue, 15 Sep 2009 05:48:20 -0700 Subject: 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(-) (limited to 'src') diff --git a/src/arch/sparc/isa/decoder.isa b/src/arch/sparc/isa/decoder.isa index e34ca033f..ce5e34ff0 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 -- cgit v1.2.3 From 9b8e61beb38af081454ffd5e06d14458080b98e0 Mon Sep 17 00:00:00 2001 From: Vince Weaver Date: Tue, 15 Sep 2009 22:36:47 -0700 Subject: 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(-) (limited to 'src') diff --git a/src/arch/alpha/linux/linux.hh b/src/arch/alpha/linux/linux.hh index c622c5ef1..e9947644c 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 9886c7ea7..0f09e472b 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 d99fa8e49..b9b10a593 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 56e3588a7..a7f36e18d 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 ee81fa18f..b30cca2fb 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 53a24487f..0fa3c382a 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 b1dc691ce..1f7567d43 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 f4781d886..c50803976 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 c2941c769..d5bead8f3 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 5a425ed9a..52352ee80 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 5f2ebd428..c00edfdc6 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 -- cgit v1.2.3 From 83eebe046481eeefe3ed9f63f63a87a78ae9fb03 Mon Sep 17 00:00:00 2001 From: Soumyaroop Roy Date: Wed, 16 Sep 2009 09:47:38 -0400 Subject: 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(-) (limited to 'src') diff --git a/src/cpu/inorder/thread_state.hh b/src/cpu/inorder/thread_state.hh index 0571b6e04..422df30aa 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; -- cgit v1.2.3 From eec6bfaa9de23b075762a62e57e46cd3f2f977ef Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Wed, 16 Sep 2009 19:28:01 -0700 Subject: 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(-) (limited to 'src') diff --git a/src/arch/x86/isa/insts/system/segmentation.py b/src/arch/x86/isa/insts/system/segmentation.py index b83fcba95..c97f2f152 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 }; -- cgit v1.2.3 From 239f1dea31144d8ea35065c8e037b88298db616f Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Wed, 16 Sep 2009 19:28:30 -0700 Subject: X86: Fix checking the NT bit during an IRET. --- .../insts/general_purpose/control_transfer/interrupts_and_exceptions.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') 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 a9ad611b7..1c0650683 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 -- cgit v1.2.3 From 7a0ef6c36fa4f188fecfd709436dfa52bb0918d6 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Wed, 16 Sep 2009 19:28:57 -0700 Subject: 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(-) (limited to 'src') diff --git a/src/arch/x86/isa/microops/regop.isa b/src/arch/x86/isa/microops/regop.isa index a4cb6f4cc..a8d50f17c 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, -- cgit v1.2.3 From c876a781a592c75b38853b2ec4b7d9435f1444cf Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Wed, 16 Sep 2009 19:29:51 -0700 Subject: 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(-) (limited to 'src') diff --git a/src/arch/x86/isa/microops/regop.isa b/src/arch/x86/isa/microops/regop.isa index a8d50f17c..fd1ad6925 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: 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(-) (limited to 'src') diff --git a/src/arch/x86/predecoder_tables.cc b/src/arch/x86/predecoder_tables.cc index 5f2b5c421..e8c838dfb 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 , -- cgit v1.2.3 From 6f7e1961131250817f6b73f5ee8cf7902bb4bba0 Mon Sep 17 00:00:00 2001 From: Korey Sewell Date: Thu, 17 Sep 2009 15:45:27 -0400 Subject: 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 | 34 ++++++++++++++++++++++++++++-- src/cpu/inorder/resources/mult_div_unit.hh | 2 ++ 2 files changed, 34 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/cpu/inorder/resources/mult_div_unit.cc b/src/cpu/inorder/resources/mult_div_unit.cc index 7592c0260..e7bd6750f 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 76180714c..d3dd0260d 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; -- cgit v1.2.3 From b7094ec38b8ec2f4de1fdf3d60a0f5953efa3e06 Mon Sep 17 00:00:00 2001 From: Korey Sewell Date: Thu, 17 Sep 2009 15:59:43 -0400 Subject: 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(-) (limited to 'src') diff --git a/src/arch/mips/linux/process.cc b/src/arch/mips/linux/process.cc index 0fa3c382a..dde3a4efd 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 5afde2be1..8c45014e0 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 3e9fb7c20..b9f608922 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 87c62330f..b8f4de20a 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); -- cgit v1.2.3 From aa78db4adab413600547dc01a9f1db2fbbe8fa44 Mon Sep 17 00:00:00 2001 From: Nathan Binkert Date: Tue, 22 Sep 2009 15:24:16 -0700 Subject: code_formatter: use __builtin__ which is correct, not __builtins__ --- src/python/m5/util/code_formatter.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/python/m5/util/code_formatter.py b/src/python/m5/util/code_formatter.py index 919a6423b..396fe0e52 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) -- cgit v1.2.3 From eec67312b5990dd73c6330e74bff978ad300f780 Mon Sep 17 00:00:00 2001 From: Nathan Binkert Date: Tue, 22 Sep 2009 15:24:16 -0700 Subject: attrdict: add pickle support to attrdict --- src/python/m5/util/attrdict.py | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'src') diff --git a/src/python/m5/util/attrdict.py b/src/python/m5/util/attrdict.py index 0b30258b9..3336632f5 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.""" -- cgit v1.2.3 From 0d58d32ad51eed32e6c7f9135b901006777fbe87 Mon Sep 17 00:00:00 2001 From: Nathan Binkert Date: Tue, 22 Sep 2009 15:24:16 -0700 Subject: multiattrdict: make multilevel nesting work properly --- src/python/m5/util/attrdict.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/python/m5/util/attrdict.py b/src/python/m5/util/attrdict.py index 3336632f5..8f7d59698 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 -- cgit v1.2.3 From 9a8cb7db7e86c25a755f2e2817a0385b13e3ac32 Mon Sep 17 00:00:00 2001 From: Nathan Binkert Date: Tue, 22 Sep 2009 15:24:16 -0700 Subject: 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 --- 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 | 9 +- 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/convert.py | 250 -------------------------------------- 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/smartdict.py | 154 ----------------------- src/python/m5/ticks.py | 2 +- src/python/m5/trace.py | 2 +- src/python/m5/util/__init__.py | 149 ++++++++++++++++++++++- src/python/m5/util/convert.py | 250 ++++++++++++++++++++++++++++++++++++++ src/python/m5/util/jobfile.py | 10 +- src/python/m5/util/misc.py | 87 ------------- src/python/m5/util/smartdict.py | 154 +++++++++++++++++++++++ src/sim/System.py | 5 +- 35 files changed, 727 insertions(+), 764 deletions(-) delete mode 100644 src/python/m5/convert.py delete mode 100644 src/python/m5/environment.py delete mode 100644 src/python/m5/smartdict.py create mode 100644 src/python/m5/util/convert.py delete mode 100644 src/python/m5/util/misc.py create mode 100644 src/python/m5/util/smartdict.py (limited to 'src') diff --git a/src/SConscript b/src/SConscript index d96922b49..687709ac1 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 dd4e4fe25..a6e4091f2 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 81c6bdacf..48ee4171c 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 c3dcf4e0b..d271bd387 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 15b03fd33..9f7dc43b3 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 +from MemObject import MemObject -if build_env['FULL_SYSTEM']: +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 4661375ba..75114053e 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 bff9af62d..132254413 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 9faadc68c..a0b0466a7 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 629fd4877..8e1b3a8d0 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 56e537ad2..3f2210e44 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 edc6dc9b6..d0c4ce537 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 37386898d..2c7b8475f 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 bfa39ead9..bbe46db18 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 93603092b..d4620cd8e 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 b7174bb43..3d72f4098 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 ce6839241..6b83c41aa 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 5135a064d..9254dc695 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 0f113cc09..b3f6b2946 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 bb892f376..935986a12 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 8ef22be4e..0e0ffaea9 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 -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 +try: + import pydot +except: + pydot = False -def isSimObjectOrSequence(value): - return isSimObject(value) or isSimObjectSequence(value) +import m5 +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 c3512cd0d..9f9459ae8 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/convert.py b/src/python/m5/convert.py deleted file mode 100644 index bb9e3e1f1..000000000 --- a/src/python/m5/convert.py +++ /dev/null @@ -1,250 +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 - -# metric prefixes -exa = 1.0e18 -peta = 1.0e15 -tera = 1.0e12 -giga = 1.0e9 -mega = 1.0e6 -kilo = 1.0e3 - -milli = 1.0e-3 -micro = 1.0e-6 -nano = 1.0e-9 -pico = 1.0e-12 -femto = 1.0e-15 -atto = 1.0e-18 - -# power of 2 prefixes -kibi = 1024 -mebi = kibi * 1024 -gibi = mebi * 1024 -tebi = gibi * 1024 -pebi = tebi * 1024 -exbi = pebi * 1024 - -# memory size configuration stuff -def toFloat(value): - if not isinstance(value, str): - raise TypeError, "wrong type '%s' should be str" % type(value) - - if value.endswith('Ei'): - return float(value[:-2]) * exbi - elif value.endswith('Pi'): - return float(value[:-2]) * pebi - elif value.endswith('Ti'): - return float(value[:-2]) * tebi - elif value.endswith('Gi'): - return float(value[:-2]) * gibi - elif value.endswith('Mi'): - return float(value[:-2]) * mebi - elif value.endswith('ki'): - return float(value[:-2]) * kibi - elif value.endswith('E'): - return float(value[:-1]) * exa - elif value.endswith('P'): - return float(value[:-1]) * peta - elif value.endswith('T'): - return float(value[:-1]) * tera - elif value.endswith('G'): - return float(value[:-1]) * giga - elif value.endswith('M'): - return float(value[:-1]) * mega - elif value.endswith('k'): - return float(value[:-1]) * kilo - elif value.endswith('m'): - return float(value[:-1]) * milli - elif value.endswith('u'): - return float(value[:-1]) * micro - elif value.endswith('n'): - return float(value[:-1]) * nano - elif value.endswith('p'): - return float(value[:-1]) * pico - elif value.endswith('f'): - return float(value[:-1]) * femto - else: - return float(value) - -def toInteger(value): - value = toFloat(value) - result = long(value) - if value != result: - raise ValueError, "cannot convert '%s' to integer" % value - - return result - -_bool_dict = { - 'true' : True, 't' : True, 'yes' : True, 'y' : True, '1' : True, - 'false' : False, 'f' : False, 'no' : False, 'n' : False, '0' : False - } - -def toBool(value): - if not isinstance(value, str): - raise TypeError, "wrong type '%s' should be str" % type(value) - - value = value.lower() - result = _bool_dict.get(value, None) - if result == None: - raise ValueError, "cannot convert '%s' to bool" % value - return result - -def toFrequency(value): - if not isinstance(value, str): - raise TypeError, "wrong type '%s' should be str" % type(value) - - if value.endswith('THz'): - return float(value[:-3]) * tera - elif value.endswith('GHz'): - return float(value[:-3]) * giga - elif value.endswith('MHz'): - return float(value[:-3]) * mega - elif value.endswith('kHz'): - return float(value[:-3]) * kilo - elif value.endswith('Hz'): - return float(value[:-2]) - - raise ValueError, "cannot convert '%s' to frequency" % value - -def toLatency(value): - if not isinstance(value, str): - raise TypeError, "wrong type '%s' should be str" % type(value) - - if value.endswith('ps'): - return float(value[:-2]) * pico - elif value.endswith('ns'): - return float(value[:-2]) * nano - elif value.endswith('us'): - return float(value[:-2]) * micro - elif value.endswith('ms'): - return float(value[:-2]) * milli - elif value.endswith('s'): - return float(value[:-1]) - - raise ValueError, "cannot convert '%s' to latency" % value - -def anyToLatency(value): - """result is a clock period""" - - if not isinstance(value, str): - raise TypeError, "wrong type '%s' should be str" % type(value) - - try: - val = toFrequency(value) - if val != 0: - val = 1 / val - return val - except ValueError: - pass - - try: - val = toLatency(value) - return val - except ValueError: - pass - - raise ValueError, "cannot convert '%s' to clock period" % value - -def anyToFrequency(value): - """result is a clock period""" - - if not isinstance(value, str): - raise TypeError, "wrong type '%s' should be str" % type(value) - - try: - val = toFrequency(value) - return val - except ValueError: - pass - - try: - val = toLatency(value) - if val != 0: - val = 1 / val - return val - except ValueError: - pass - - raise ValueError, "cannot convert '%s' to clock period" % value - -def toNetworkBandwidth(value): - if not isinstance(value, str): - raise TypeError, "wrong type '%s' should be str" % type(value) - - if value.endswith('Tbps'): - return float(value[:-4]) * tera - elif value.endswith('Gbps'): - return float(value[:-4]) * giga - elif value.endswith('Mbps'): - return float(value[:-4]) * mega - elif value.endswith('kbps'): - return float(value[:-4]) * kilo - elif value.endswith('bps'): - return float(value[:-3]) - else: - return float(value) - - raise ValueError, "cannot convert '%s' to network bandwidth" % value - -def toMemoryBandwidth(value): - if not isinstance(value, str): - raise TypeError, "wrong type '%s' should be str" % type(value) - - if value.endswith('PB/s'): - return float(value[:-4]) * pebi - elif value.endswith('TB/s'): - return float(value[:-4]) * tebi - elif value.endswith('GB/s'): - return float(value[:-4]) * gibi - elif value.endswith('MB/s'): - return float(value[:-4]) * mebi - elif value.endswith('kB/s'): - return float(value[:-4]) * kibi - elif value.endswith('B/s'): - return float(value[:-3]) - - raise ValueError, "cannot convert '%s' to memory bandwidth" % value - -def toMemorySize(value): - if not isinstance(value, str): - raise TypeError, "wrong type '%s' should be str" % type(value) - - if value.endswith('PB'): - return long(value[:-2]) * pebi - elif value.endswith('TB'): - return long(value[:-2]) * tebi - elif value.endswith('GB'): - return long(value[:-2]) * gibi - elif value.endswith('MB'): - return long(value[:-2]) * mebi - elif value.endswith('kB'): - return long(value[:-2]) * kibi - elif value.endswith('B'): - return long(value[:-1]) - - raise ValueError, "cannot convert '%s' to memory size" % value diff --git a/src/python/m5/environment.py b/src/python/m5/environment.py deleted file mode 100644 index bea0bc1d0..000000000 --- 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 2a308ff09..29f8cc976 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 edd78fa28..3a3a30014 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 45992fe85..092bd0339 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/smartdict.py b/src/python/m5/smartdict.py deleted file mode 100644 index d85dbd517..000000000 --- a/src/python/m5/smartdict.py +++ /dev/null @@ -1,154 +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 - -# The SmartDict class fixes a couple of issues with using the content -# of os.environ or similar dicts of strings as Python variables: -# -# 1) Undefined variables should return False rather than raising KeyError. -# -# 2) String values of 'False', '0', etc., should evaluate to False -# (not just the empty string). -# -# #1 is solved by overriding __getitem__, and #2 is solved by using a -# proxy class for values and overriding __nonzero__ on the proxy. -# Everything else is just to (a) make proxies behave like normal -# values otherwise, (b) make sure any dict operation returns a proxy -# rather than a normal value, and (c) coerce values written to the -# dict to be strings. - - -from convert import * - -class Variable(str): - """Intelligent proxy class for SmartDict. Variable will use the - various convert functions to attempt to convert values to useable - types""" - def __int__(self): - return toInteger(str(self)) - def __long__(self): - return toLong(str(self)) - def __float__(self): - return toFloat(str(self)) - def __nonzero__(self): - return toBool(str(self)) - def convert(self, other): - t = type(other) - if t == bool: - return bool(self) - if t == int: - return int(self) - if t == long: - return long(self) - if t == float: - return float(self) - return str(self) - def __lt__(self, other): - return self.convert(other) < other - def __le__(self, other): - return self.convert(other) <= other - def __eq__(self, other): - return self.convert(other) == other - def __ne__(self, other): - return self.convert(other) != other - def __gt__(self, other): - return self.convert(other) > other - def __ge__(self, other): - return self.convert(other) >= other - - def __add__(self, other): - return self.convert(other) + other - def __sub__(self, other): - return self.convert(other) - other - def __mul__(self, other): - return self.convert(other) * other - def __div__(self, other): - return self.convert(other) / other - def __truediv__(self, other): - return self.convert(other) / other - - def __radd__(self, other): - return other + self.convert(other) - def __rsub__(self, other): - return other - self.convert(other) - def __rmul__(self, other): - return other * self.convert(other) - def __rdiv__(self, other): - return other / self.convert(other) - def __rtruediv__(self, other): - return other / self.convert(other) - -class UndefinedVariable(object): - """Placeholder class to represent undefined variables. Will - generally cause an exception whenever it is used, but evaluates to - zero for boolean truth testing such as in an if statement""" - def __nonzero__(self): - return False - -class SmartDict(dict): - """Dictionary class that holds strings, but intelligently converts - those strings to other types depending on their usage""" - - def __getitem__(self, key): - """returns a Variable proxy if the values exists in the database and - returns an UndefinedVariable otherwise""" - - if key in self: - return Variable(dict.get(self, key)) - else: - # Note that this does *not* change the contents of the dict, - # so that even after we call env['foo'] we still get a - # meaningful answer from "'foo' in env" (which - # calls dict.__contains__, which we do not override). - return UndefinedVariable() - - def __setitem__(self, key, item): - """intercept the setting of any variable so that we always - store strings in the dict""" - dict.__setitem__(self, key, str(item)) - - def values(self): - return [ Variable(v) for v in dict.values(self) ] - - def itervalues(self): - for value in dict.itervalues(self): - yield Variable(value) - - def items(self): - return [ (k, Variable(v)) for k,v in dict.items(self) ] - - def iteritems(self): - for key,value in dict.iteritems(self): - yield key, Variable(value) - - def get(self, key, default='False'): - return Variable(dict.get(self, key, str(default))) - - def setdefault(self, key, default='False'): - return Variable(dict.setdefault(self, key, str(default))) - -__all__ = [ 'SmartDict' ] diff --git a/src/python/m5/ticks.py b/src/python/m5/ticks.py index 91834c9c8..181a65eba 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 17aa6196c..db239040a 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 3930c8b6f..7a674dd2d 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 +import os +import re +import sys + +import convert +import jobfile + from attrdict import attrdict, optiondict from code_formatter import code_formatter -from misc import * from multidict import multidict from orderdict import orderdict -import jobfile +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) -def print_list(items, indent=4): +# 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/util/convert.py b/src/python/m5/util/convert.py new file mode 100644 index 000000000..bb9e3e1f1 --- /dev/null +++ b/src/python/m5/util/convert.py @@ -0,0 +1,250 @@ +# 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 + +# metric prefixes +exa = 1.0e18 +peta = 1.0e15 +tera = 1.0e12 +giga = 1.0e9 +mega = 1.0e6 +kilo = 1.0e3 + +milli = 1.0e-3 +micro = 1.0e-6 +nano = 1.0e-9 +pico = 1.0e-12 +femto = 1.0e-15 +atto = 1.0e-18 + +# power of 2 prefixes +kibi = 1024 +mebi = kibi * 1024 +gibi = mebi * 1024 +tebi = gibi * 1024 +pebi = tebi * 1024 +exbi = pebi * 1024 + +# memory size configuration stuff +def toFloat(value): + if not isinstance(value, str): + raise TypeError, "wrong type '%s' should be str" % type(value) + + if value.endswith('Ei'): + return float(value[:-2]) * exbi + elif value.endswith('Pi'): + return float(value[:-2]) * pebi + elif value.endswith('Ti'): + return float(value[:-2]) * tebi + elif value.endswith('Gi'): + return float(value[:-2]) * gibi + elif value.endswith('Mi'): + return float(value[:-2]) * mebi + elif value.endswith('ki'): + return float(value[:-2]) * kibi + elif value.endswith('E'): + return float(value[:-1]) * exa + elif value.endswith('P'): + return float(value[:-1]) * peta + elif value.endswith('T'): + return float(value[:-1]) * tera + elif value.endswith('G'): + return float(value[:-1]) * giga + elif value.endswith('M'): + return float(value[:-1]) * mega + elif value.endswith('k'): + return float(value[:-1]) * kilo + elif value.endswith('m'): + return float(value[:-1]) * milli + elif value.endswith('u'): + return float(value[:-1]) * micro + elif value.endswith('n'): + return float(value[:-1]) * nano + elif value.endswith('p'): + return float(value[:-1]) * pico + elif value.endswith('f'): + return float(value[:-1]) * femto + else: + return float(value) + +def toInteger(value): + value = toFloat(value) + result = long(value) + if value != result: + raise ValueError, "cannot convert '%s' to integer" % value + + return result + +_bool_dict = { + 'true' : True, 't' : True, 'yes' : True, 'y' : True, '1' : True, + 'false' : False, 'f' : False, 'no' : False, 'n' : False, '0' : False + } + +def toBool(value): + if not isinstance(value, str): + raise TypeError, "wrong type '%s' should be str" % type(value) + + value = value.lower() + result = _bool_dict.get(value, None) + if result == None: + raise ValueError, "cannot convert '%s' to bool" % value + return result + +def toFrequency(value): + if not isinstance(value, str): + raise TypeError, "wrong type '%s' should be str" % type(value) + + if value.endswith('THz'): + return float(value[:-3]) * tera + elif value.endswith('GHz'): + return float(value[:-3]) * giga + elif value.endswith('MHz'): + return float(value[:-3]) * mega + elif value.endswith('kHz'): + return float(value[:-3]) * kilo + elif value.endswith('Hz'): + return float(value[:-2]) + + raise ValueError, "cannot convert '%s' to frequency" % value + +def toLatency(value): + if not isinstance(value, str): + raise TypeError, "wrong type '%s' should be str" % type(value) + + if value.endswith('ps'): + return float(value[:-2]) * pico + elif value.endswith('ns'): + return float(value[:-2]) * nano + elif value.endswith('us'): + return float(value[:-2]) * micro + elif value.endswith('ms'): + return float(value[:-2]) * milli + elif value.endswith('s'): + return float(value[:-1]) + + raise ValueError, "cannot convert '%s' to latency" % value + +def anyToLatency(value): + """result is a clock period""" + + if not isinstance(value, str): + raise TypeError, "wrong type '%s' should be str" % type(value) + + try: + val = toFrequency(value) + if val != 0: + val = 1 / val + return val + except ValueError: + pass + + try: + val = toLatency(value) + return val + except ValueError: + pass + + raise ValueError, "cannot convert '%s' to clock period" % value + +def anyToFrequency(value): + """result is a clock period""" + + if not isinstance(value, str): + raise TypeError, "wrong type '%s' should be str" % type(value) + + try: + val = toFrequency(value) + return val + except ValueError: + pass + + try: + val = toLatency(value) + if val != 0: + val = 1 / val + return val + except ValueError: + pass + + raise ValueError, "cannot convert '%s' to clock period" % value + +def toNetworkBandwidth(value): + if not isinstance(value, str): + raise TypeError, "wrong type '%s' should be str" % type(value) + + if value.endswith('Tbps'): + return float(value[:-4]) * tera + elif value.endswith('Gbps'): + return float(value[:-4]) * giga + elif value.endswith('Mbps'): + return float(value[:-4]) * mega + elif value.endswith('kbps'): + return float(value[:-4]) * kilo + elif value.endswith('bps'): + return float(value[:-3]) + else: + return float(value) + + raise ValueError, "cannot convert '%s' to network bandwidth" % value + +def toMemoryBandwidth(value): + if not isinstance(value, str): + raise TypeError, "wrong type '%s' should be str" % type(value) + + if value.endswith('PB/s'): + return float(value[:-4]) * pebi + elif value.endswith('TB/s'): + return float(value[:-4]) * tebi + elif value.endswith('GB/s'): + return float(value[:-4]) * gibi + elif value.endswith('MB/s'): + return float(value[:-4]) * mebi + elif value.endswith('kB/s'): + return float(value[:-4]) * kibi + elif value.endswith('B/s'): + return float(value[:-3]) + + raise ValueError, "cannot convert '%s' to memory bandwidth" % value + +def toMemorySize(value): + if not isinstance(value, str): + raise TypeError, "wrong type '%s' should be str" % type(value) + + if value.endswith('PB'): + return long(value[:-2]) * pebi + elif value.endswith('TB'): + return long(value[:-2]) * tebi + elif value.endswith('GB'): + return long(value[:-2]) * gibi + elif value.endswith('MB'): + return long(value[:-2]) * mebi + elif value.endswith('kB'): + return long(value[:-2]) * kibi + elif value.endswith('B'): + return long(value[:-1]) + + raise ValueError, "cannot convert '%s' to memory size" % value diff --git a/src/python/m5/util/jobfile.py b/src/python/m5/util/jobfile.py index c830895f6..9c59778e5 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 094e3ed9a..000000000 --- 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/util/smartdict.py b/src/python/m5/util/smartdict.py new file mode 100644 index 000000000..d85dbd517 --- /dev/null +++ b/src/python/m5/util/smartdict.py @@ -0,0 +1,154 @@ +# 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 + +# The SmartDict class fixes a couple of issues with using the content +# of os.environ or similar dicts of strings as Python variables: +# +# 1) Undefined variables should return False rather than raising KeyError. +# +# 2) String values of 'False', '0', etc., should evaluate to False +# (not just the empty string). +# +# #1 is solved by overriding __getitem__, and #2 is solved by using a +# proxy class for values and overriding __nonzero__ on the proxy. +# Everything else is just to (a) make proxies behave like normal +# values otherwise, (b) make sure any dict operation returns a proxy +# rather than a normal value, and (c) coerce values written to the +# dict to be strings. + + +from convert import * + +class Variable(str): + """Intelligent proxy class for SmartDict. Variable will use the + various convert functions to attempt to convert values to useable + types""" + def __int__(self): + return toInteger(str(self)) + def __long__(self): + return toLong(str(self)) + def __float__(self): + return toFloat(str(self)) + def __nonzero__(self): + return toBool(str(self)) + def convert(self, other): + t = type(other) + if t == bool: + return bool(self) + if t == int: + return int(self) + if t == long: + return long(self) + if t == float: + return float(self) + return str(self) + def __lt__(self, other): + return self.convert(other) < other + def __le__(self, other): + return self.convert(other) <= other + def __eq__(self, other): + return self.convert(other) == other + def __ne__(self, other): + return self.convert(other) != other + def __gt__(self, other): + return self.convert(other) > other + def __ge__(self, other): + return self.convert(other) >= other + + def __add__(self, other): + return self.convert(other) + other + def __sub__(self, other): + return self.convert(other) - other + def __mul__(self, other): + return self.convert(other) * other + def __div__(self, other): + return self.convert(other) / other + def __truediv__(self, other): + return self.convert(other) / other + + def __radd__(self, other): + return other + self.convert(other) + def __rsub__(self, other): + return other - self.convert(other) + def __rmul__(self, other): + return other * self.convert(other) + def __rdiv__(self, other): + return other / self.convert(other) + def __rtruediv__(self, other): + return other / self.convert(other) + +class UndefinedVariable(object): + """Placeholder class to represent undefined variables. Will + generally cause an exception whenever it is used, but evaluates to + zero for boolean truth testing such as in an if statement""" + def __nonzero__(self): + return False + +class SmartDict(dict): + """Dictionary class that holds strings, but intelligently converts + those strings to other types depending on their usage""" + + def __getitem__(self, key): + """returns a Variable proxy if the values exists in the database and + returns an UndefinedVariable otherwise""" + + if key in self: + return Variable(dict.get(self, key)) + else: + # Note that this does *not* change the contents of the dict, + # so that even after we call env['foo'] we still get a + # meaningful answer from "'foo' in env" (which + # calls dict.__contains__, which we do not override). + return UndefinedVariable() + + def __setitem__(self, key, item): + """intercept the setting of any variable so that we always + store strings in the dict""" + dict.__setitem__(self, key, str(item)) + + def values(self): + return [ Variable(v) for v in dict.values(self) ] + + def itervalues(self): + for value in dict.itervalues(self): + yield Variable(value) + + def items(self): + return [ (k, Variable(v)) for k,v in dict.items(self) ] + + def iteritems(self): + for key,value in dict.iteritems(self): + yield key, Variable(value) + + def get(self, key, default='False'): + return Variable(dict.get(self, key, str(default))) + + def setdefault(self, key, default='False'): + return Variable(dict.setdefault(self, key, str(default))) + +__all__ = [ 'SmartDict' ] diff --git a/src/sim/System.py b/src/sim/System.py index 3b0bc1e46..06a54a78d 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") -- cgit v1.2.3 From e9288b2cd35863c600d7ff7bf04f4c08e055e3e0 Mon Sep 17 00:00:00 2001 From: Nathan Binkert Date: Tue, 22 Sep 2009 15:24:16 -0700 Subject: scons: add slicc and ply to sys.path and PYTHONPATH so everyone has access --- src/arch/isa_parser.py | 5 ----- src/arch/micro_asm.py | 4 ---- src/mem/protocol/SConscript | 1 - 3 files changed, 10 deletions(-) (limited to 'src') diff --git a/src/arch/isa_parser.py b/src/arch/isa_parser.py index d5b5bbe4f..23260ca48 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 3433a8076..4e5400cef 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 293346f13..700ab40ea 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]) -- cgit v1.2.3 From 30d5d95b6a7c93ccf63ae0cfcc62d17306c31eee Mon Sep 17 00:00:00 2001 From: Nathan Binkert Date: Tue, 22 Sep 2009 15:24:16 -0700 Subject: params: small cleanup to param description internals --- src/SConscript | 7 +------ src/python/m5/params.py | 6 +++++- 2 files changed, 6 insertions(+), 7 deletions(-) (limited to 'src') diff --git a/src/SConscript b/src/SConscript index 687709ac1..d3323f0a0 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 3a3a30014..cf64070c5 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): -- cgit v1.2.3 From 2278363015a2a5cc850b38213833096d33b496e8 Mon Sep 17 00:00:00 2001 From: Nathan Binkert Date: Tue, 22 Sep 2009 18:12:39 -0700 Subject: 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 | 82 +- 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 + src/mem/slicc/ast/CheckAllocateStatementAST.cc | 72 - src/mem/slicc/ast/CheckAllocateStatementAST.hh | 82 -- src/mem/slicc/ast/CheckAllocateStatementAST.py | 47 + src/mem/slicc/ast/CheckStopSlotsStatementAST.cc | 115 -- src/mem/slicc/ast/CheckStopSlotsStatementAST.hh | 85 -- src/mem/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 + 177 files changed, 6477 insertions(+), 15231 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 (limited to 'src') diff --git a/src/mem/protocol/SConscript b/src/mem/protocol/SConscript index 700ab40ea..425219580 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() -protocol = env['PROTOCOL'] -sources = [ protocol_dir.File("RubySlicc_interfaces.slicc"), - protocol_dir.File("%s.slicc" % protocol) ] + print "SLICC Generator pass 2..." + slicc.generate() -execfile(slicc_dir.File('parser/parser.py').srcnode().abspath) + print "SLICC writing C++ files..." + slicc.writeCodeFiles(pdir) -sm_files = read_slicc([s.srcnode().abspath for s in sources]) -sm_files = [ protocol_dir.File(f) for f in sm_files ] + print "SLICC writing HTML files..." + slicc.writeHTMLFiles(hdir) -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_builder = Builder(action=slicc_action, emitter=slicc_emitter) -slicc_bin = slicc_dir.File("slicc") +protocol = env['PROTOCOL'] +sources = [ protocol_dir.File("RubySlicc_interfaces.slicc"), + protocol_dir.File("%s.slicc" % protocol) ] 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 e26ceb979..000000000 --- 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 000000000..8ce04e77d --- /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 e893c453a..000000000 --- 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 33c9b84ed..000000000 --- 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 000000000..5b1b124cd --- /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 3363fbb09..000000000 --- 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 e46412ff7..000000000 --- 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 4970ee254..000000000 --- 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 000000000..18bf443b9 --- /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 8cf42aa63..000000000 --- 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 2c19da831..000000000 --- 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 000000000..f8e77b03b --- /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 1f498efe2..000000000 --- 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 1df853514..000000000 --- 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 000000000..b96153b0a --- /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 38dc449d6..000000000 --- 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 6de068caa..000000000 --- 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 000000000..307fbd6a1 --- /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 61dccf2c0..000000000 --- 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 1f22a79e4..000000000 --- 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 000000000..841220c94 --- /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 8d455eb9d..000000000 --- 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 53d479136..000000000 --- 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 000000000..ba9970975 --- /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 6ccf9a9d6..000000000 --- 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 d9e4555b4..000000000 --- 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 000000000..2303725a3 --- /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 8337d714b..000000000 --- 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 1c2bc3c05..000000000 --- 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 000000000..42f98afc7 --- /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 a422d8a28..000000000 --- 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 fc2776ed7..000000000 --- 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 000000000..faf966460 --- /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 b051f3c8f..000000000 --- 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 2af650e83..000000000 --- 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 000000000..c16fc8a75 --- /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 0d8af0e9f..000000000 --- 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 8af1c8891..000000000 --- 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 000000000..9cb76a8a1 --- /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 3427d4dd9..000000000 --- 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 9566541da..000000000 --- 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 000000000..70a0aa0b5 --- /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 f4bffaab3..000000000 --- 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 a47e86af5..000000000 --- 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 000000000..b16d1d072 --- /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 529811f25..000000000 --- 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 ca27948b7..000000000 --- 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 000000000..b169cbb1c --- /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 5b19017e9..000000000 --- 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 6c02122ee..000000000 --- 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 000000000..abf7eec7b --- /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 2a0905f06..000000000 --- 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 205e71a85..000000000 --- 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 000000000..7ff3bf8a7 --- /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 40942a58d..000000000 --- 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 2c168913a..000000000 --- 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 000000000..788876fd1 --- /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 f62af9921..000000000 --- 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 e6295a6e2..000000000 --- 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 000000000..3dde24557 --- /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 40719fc66..000000000 --- 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 f97ab8805..000000000 --- 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 000000000..c4fb4a4db --- /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 4e384a3b3..000000000 --- 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 c895fa9ae..000000000 --- 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 000000000..773e8f35c --- /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 fd224fe2f..000000000 --- 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 c9e20418e..000000000 --- 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 ae8026458..000000000 --- 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 5d1bc2a1c..000000000 --- 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 000000000..8d48ccbf5 --- /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 1bcfdc7f1..000000000 --- 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 34b694882..000000000 --- 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 000000000..113bb188a --- /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 1bfe312ff..000000000 --- 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 d248e6ba4..000000000 --- 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 000000000..ecfe43cdb --- /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 95e57192f..000000000 --- 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 375f130d6..000000000 --- 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 000000000..a42350768 --- /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 3569395db..000000000 --- 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 0b808f472..000000000 --- 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 000000000..8a967f7b8 --- /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 56a377f23..000000000 --- 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 0aa0172d3..000000000 --- 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 000000000..e6ef31928 --- /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 c42843cce..000000000 --- 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 d1bb99b93..000000000 --- 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 000000000..347f4d361 --- /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 76892d437..000000000 --- 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 7edcdc1e7..000000000 --- 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 000000000..6afe3f4fa --- /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 3e92446dd..000000000 --- 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 e8c65ce4f..000000000 --- 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 000000000..5186bf0d5 --- /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 8ec937c87..000000000 --- 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 1fa1b36d6..000000000 --- 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 000000000..1d08a7234 --- /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 35627722a..000000000 --- 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 000000000..017b2b1ed --- /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 0f5817f7c..000000000 --- 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 831e2481a..000000000 --- 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 000000000..1475c5c97 --- /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 66b7ca132..000000000 --- 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 f07f0a3c2..000000000 --- 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 000000000..ef745fd50 --- /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 7590b4e7c..000000000 --- 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 f8e1fdc24..000000000 --- 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 000000000..209859b8d --- /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 bbf2f8491..000000000 --- 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 8a72c0406..000000000 --- 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 000000000..d2cc04eff --- /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 5657d023c..000000000 --- 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 144372047..000000000 --- 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 000000000..7dd4c74aa --- /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 1a02f7edd..000000000 --- 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 cd02f03bb..000000000 --- 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 000000000..d068666ad --- /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 1fe0f6d4b..000000000 --- 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 47355f3ac..000000000 --- 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 000000000..285d5b622 --- /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 03c528f87..000000000 --- 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 10d53ef80..000000000 --- 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 000000000..337b15597 --- /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 13e265540..000000000 --- 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 ea32582a2..000000000 --- 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 000000000..ac440bb68 --- /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 000000000..de50cbd49 --- /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 000000000..e69de29bb diff --git a/src/mem/slicc/generate/dot.py b/src/mem/slicc/generate/dot.py new file mode 100644 index 000000000..762658983 --- /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 000000000..53252ce3c --- /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 000000000..97c63ebc6 --- /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 15eccd3ca..000000000 --- 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 81b7306bc..000000000 --- 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 2d35dccb6..000000000 --- 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 6b1f8ea92..000000000 --- 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 2dca149b4..000000000 --- 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 6da75f748..000000000 --- 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 294925ee1..000000000 --- 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 a10dcca53..000000000 --- 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 000000000..0bc2ef37a --- /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 000000000..0e5ccc885 --- /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 b2d36855b..000000000 --- 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 7fecfd273..000000000 --- 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 c8cef3b21..000000000 --- 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 40a00c9d2..000000000 --- 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 dbb0c836a..000000000 --- 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 000000000..880fab15a --- /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 40cefc982..000000000 --- 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 000000000..9ff4d8ba7 --- /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 d29138b38..000000000 --- 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 000000000..5c812a96f --- /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 39900d506..000000000 --- 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 000000000..123693256 --- /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 86f92b692..000000000 --- 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 f5f3ab073..000000000 --- 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 000000000..e54d6a435 --- /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 25af5ad47..000000000 --- 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 4a1c5e44e..000000000 --- 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 000000000..b394fda44 --- /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 8af3685f8..000000000 --- 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 90d3f48c3..000000000 --- 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 000000000..17d7dfad3 --- /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 d6d348166..000000000 --- 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 75d6da4e9..000000000 --- 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 000000000..1bf09048a --- /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 5afe53423..000000000 --- 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 000000000..2541296dc --- /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 a6e8dfd55..000000000 --- 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 4cb504296..000000000 --- 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 000000000..87a101f65 --- /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 000000000..43388a5fe --- /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 000000000..abadc3e30 --- /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' ] -- cgit v1.2.3 From d9f39c8ce75aac84c88b32392c2967344362906b Mon Sep 17 00:00:00 2001 From: Nathan Binkert Date: Wed, 23 Sep 2009 08:34:21 -0700 Subject: arch: nuke arch/isa_specific.hh and move stuff to generated config/the_isa.hh --- 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 ++- 124 files changed, 202 insertions(+), 150 deletions(-) delete mode 100644 src/arch/isa_specific.hh (limited to 'src') diff --git a/src/SConscript b/src/SConscript index d3323f0a0..705d76b1d 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 3f9c91096..c5225455c 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 de070bbf9..000000000 --- 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 0aba2d999..4e138a6dd 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 05d8129d0..4248c070a 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 6c301b10e..c54379c23 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 441d9b5dd..bfeec0870 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 f4ff88209..31206c81e 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 4ee7d2f2c..70c91ceda 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 26571ed68..81f494630 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 d38bd2915..ef7d4c643 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 ea53fb6f5..07be700bb 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 4107ac3b4..486edc87b 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/inorder/inorder_dyn_inst.hh" -#include "cpu/inorder/thread_context.hh" -#include "cpu/inorder/thread_state.hh" +#include "cpu/exetrace.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/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/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 9fb8e0df4..3320532ba 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 9f0927b2f..5ab839615 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 a91c6a763..522b4e8d7 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 f12a1b7a9..90c94a4f5 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 46b1cbad0..dc0378bf3 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 a405b1fb9..51782a588 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 ba2a8c8a3..b78e211bb 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 2ed8586aa..0e8526fa1 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 905de0794..ecac5fff0 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 5677810f6..eb66e10f8 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 8946ad5d3..c467e9771 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 033c318f2..33f5aba1a 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 bc809b040..1d0b92075 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 3e18d47cb..a4495564b 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 21df1d053..bb308b0ea 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 cc534ef3e..2e5a9666a 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 95bade36a..0410d6b24 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 1c08bd822..5c62c7751 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 2f1652c08..36392d054 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 8247bf1fb..41d16b633 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 2489c525f..820f3077f 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 145075dc1..ec51b80e7 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 5face4391..f1980c713 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 1378ac135..ed3471761 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 7286f1b6f..aa0f79272 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 6722941e4..de1e24201 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 0cc8eab78..65170d8b2 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 86f87991c..1b76de132 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 3ef42e91f..e1279f82b 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 9cbc50899..425c34428 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 3781113bd..5c6e287dc 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 e28c4910e..96289f641 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 ba29df196..751a26afd 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 4b29b4daa..ffccd4a84 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 a917caef3..6ff36d929 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 edc8c9b3f..9ee1de45a 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 d6beecdc5..e252fa362 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 734b63105..8c21dda0a 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 e4cc2674b..ce206435c 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 896c66f3e..51d8db4d8 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 657bc8d06..bdea07d1a 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 e7f8b7949..ae1e13717 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 ed5c6ac20..695b3b91a 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 e631c9244..940d460ce 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 5e36332af..a16986c99 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 f86b882d1..c09dd9046 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 a39f383ba..cca72ef18 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 8519917f5..bfefb9428 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 38fc89e3f..3809db00d 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 516823b47..884136927 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 798b628d6..2d4d225c7 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 47be245e5..d8e402b65 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 833aa0581..dd44adf6e 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 86d4531a0..cbc386cb0 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 6e9bb77af..ee0312969 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 4d290a1e9..c714c5d38 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 0b67d9635..9a5579158 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 67bab7337..e8071e2b3 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 7687fdf60..b241dea73 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 971fba886..638b9d86c 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 9606ed24d..dd856b5a7 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 83da618f8..cd4f5457e 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 732bb637b..0104e1b1f 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 466d0d1c9..39961fb88 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 672fd9414..8d3bae3f6 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 22bc283a3..92c6ad69b 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 8a44eba37..2d28607b4 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 b1298e0e9..fdec09756 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 ab105a435..f2083ef08 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 9e34204ef..78ecdacf2 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 5c7c0ea56..cf637aeda 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 b6478fe22..b36b5977d 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 52a2aea14..fd76fd93e 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 9c88904e3..8b06f5170 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 4df7d1150..df980cf79 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 6cdee0310..356574c71 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 83faf508e..fe93924f9 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 1401fe9ee..73dc9f116 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 265977665..b2d5069c5 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 7f04789db..5a738a9b4 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 b357e3b61..035433021 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 912ca7f0f..86f081ec5 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 2b51a6245..a91a5abf9 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 133f70b0b..86090e048 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 81132ac65..c7243cfb8 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 88fb358ef..c00d942c9 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 93f71f49b..e3eacaaa2 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 7dc1d8711..e3449abf6 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 da9564b7e..5c6ee073d 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 6fd9e1563..bd01ed9ed 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 517aad6fa..207d30792 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 bf46e0de4..c2bdd2776 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 4867df559..460f75dea 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 599353b88..bd9eb9acc 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 f20a306cb..f0e244a09 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 f70d508b2..fca9606fc 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 bf35932a6..4bc3a4434 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 3ce720ad4..0d93d37c7 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 d87ad3b22..be4086cd9 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 989cfd338..bc9592164 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 4d9f8051f..2fb529e12 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 54de6625e..700229b23 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 15be45c2a..ab061c019 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 5aa57755a..339a57f90 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 55bd2f209..ec6ac0449 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 05a48071a..7922ce073 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 6182150d4..cf063818b 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 811bdb73a..bd66594af 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 c00edfdc6..c9ce4b14f 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 f10167bba..da77f1995 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 aa89866bd..eabbc8351 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(); -- cgit v1.2.3 From be0d74d6f6a4af96b975b40782bc28cfae78f624 Mon Sep 17 00:00:00 2001 From: Nathan Binkert Date: Wed, 23 Sep 2009 18:17:11 -0700 Subject: ruby: Disable all debug output by default --- src/mem/ruby/config/defaults.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/mem/ruby/config/defaults.rb b/src/mem/ruby/config/defaults.rb index 60f32ca14..160f25411 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 -- cgit v1.2.3 From bae6a4a4d9ab3953051fb9d1b866172ecfcbccdb Mon Sep 17 00:00:00 2001 From: Nathan Binkert Date: Wed, 23 Sep 2009 18:28:29 -0700 Subject: ply grammar: Fixup Tokenizer class so you can get lexer arguments --- src/python/m5/util/grammar.py | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'src') diff --git a/src/python/m5/util/grammar.py b/src/python/m5/util/grammar.py index 93c2c84c4..ab5f35868 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 = {} -- cgit v1.2.3 From baca1f0566b51a24fda506dc95e3baa6265280d4 Mon Sep 17 00:00:00 2001 From: Nathan Binkert Date: Wed, 23 Sep 2009 18:28:29 -0700 Subject: 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 | 1376 ++++++++++++++++++++++++------------------------ 1 file changed, 691 insertions(+), 685 deletions(-) (limited to 'src') diff --git a/src/arch/isa_parser.py b/src/arch/isa_parser.py index 23260ca48..f001eff41 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 - -##################################################################### -# -# 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' +from m5.util.grammar import Grammar + +class ISAParser(Grammar): + def __init__(self, *args, **kwargs): + super(ISAParser, self).__init__(*args, **kwargs) + self.templateMap = {} + + ##################################################################### + # + # 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', - - # 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' -) - -# 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 - - -# "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 - -def t_CPPDIRECTIVE(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_ENDFILE(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. -# - -# Newlines -def t_NEWLINE(t): - r'\n+' - t.lexer.lineno += t.value.count('\n') - -# Comments -def t_comment(t): - r'//.*' - -# 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) - -# 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]). -##################################################################### - -# 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(''' + # 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(self, t): + r'[A-Za-z_]\w*' + t.type = self.reserved_map.get(t.value, 'ID') + return t + + # 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 + + # 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(self, t): + r"(?m)\{\{([^\}]|}(?!\}))+\}\}" + # strip off {{ & }} + t.value = t.value[2:-2] + 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(self, t): + r'^\#\#newfile\s+"[\w/.-]*"' + fileNameStack.push((t.value[11:-1], t.lexer.lineno)) + t.lexer.lineno = 0 + + 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. + # + + # Newlines + def t_NEWLINE(self, t): + r'\n+' + t.lexer.lineno += t.value.count('\n') + + # Comments + def t_comment(self, t): + r'//.*' + + # Completely ignored characters + t_ignore = ' \t\x0c' + + # Error handler + def t_error(self, t): + error(t.lexer.lineno, "illegal character '%s'" % t.value[0]) + t.skip(1) + + ##################################################################### + # + # 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(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] = [] + # 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) -# -# 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 -# 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 -- cgit v1.2.3 From 25d1f2728ad848272d572bb5829f8df35594f783 Mon Sep 17 00:00:00 2001 From: Korey Sewell Date: Fri, 25 Sep 2009 11:18:55 -0400 Subject: inorder-debug: fix cpu tick debug message --- src/cpu/inorder/cpu.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/cpu/inorder/cpu.cc b/src/cpu/inorder/cpu.cc index 486edc87b..969359fae 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)); } } -- cgit v1.2.3 From f28ea7a6c9ea9506524adff0f468d6dd789c510c Mon Sep 17 00:00:00 2001 From: Steve Reinhardt Date: Sat, 26 Sep 2009 10:50:50 -0700 Subject: 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(+) (limited to 'src') diff --git a/src/cpu/o3/fetch_impl.hh b/src/cpu/o3/fetch_impl.hh index 5c6e287dc..e6815ef8a 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; -- cgit v1.2.3 From 72cfed41641bbea2ea3dc78958ed3b1e2c27bbf9 Mon Sep 17 00:00:00 2001 From: Steve Reinhardt Date: Sat, 26 Sep 2009 10:50:50 -0700 Subject: 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(-) (limited to 'src') diff --git a/src/mem/cache/BaseCache.py b/src/mem/cache/BaseCache.py index bdef07cb4..5ded05400 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 80b7c545c..d8630c1f5 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 f0e244a09..ad7a0c882 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 b5f33a455..e3c0cbf16 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; -- cgit v1.2.3 From f67963078883cdb62094ca187a40a79d773251a7 Mon Sep 17 00:00:00 2001 From: Steve Reinhardt Date: Sat, 26 Sep 2009 10:50:50 -0700 Subject: 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(-) (limited to 'src') diff --git a/src/mem/cache/base.hh b/src/mem/cache/base.hh index 24f993383..c245fecd2 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 d8630c1f5..429928c79 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 -- cgit v1.2.3 From 4bec4702e9338735f58f0769f853ddff3657850e Mon Sep 17 00:00:00 2001 From: Steve Reinhardt Date: Sat, 26 Sep 2009 10:50:50 -0700 Subject: 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(-) (limited to 'src') diff --git a/src/cpu/SConscript b/src/cpu/SConscript index ea79b622c..b89a589c6 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 aa0f79272..cb5f23814 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; } -- cgit v1.2.3 From 160bcf4442df44b410c61c2d842696cb23b796f7 Mon Sep 17 00:00:00 2001 From: Nathan Binkert Date: Sat, 26 Sep 2009 12:51:37 -0700 Subject: python: Fix m5.defines so grabbing flags works correctly --- src/SConscript | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/SConscript b/src/SConscript index 705d76b1d..35753ce4c 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])) -- cgit v1.2.3 From 1290a5f340db08215bee9b0c02173ead53b95050 Mon Sep 17 00:00:00 2001 From: Lisa Hsu Date: Tue, 29 Sep 2009 18:03:10 -0400 Subject: commit Soumyaroop's bug catch about max_insts_all_threads --- src/cpu/base.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/cpu/base.cc b/src/cpu/base.cc index e4cb79344..556e7ec6f 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); } } -- cgit v1.2.3 From f09f84da6ef01870991345539edae46b401cf311 Mon Sep 17 00:00:00 2001 From: Korey Sewell Date: Thu, 1 Oct 2009 09:35:06 -0400 Subject: inorder-debug: print out workload --- src/cpu/inorder/cpu.cc | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'src') diff --git a/src/cpu/inorder/cpu.cc b/src/cpu/inorder/cpu.cc index 969359fae..1e3fdc40e 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 -- cgit v1.2.3 From 86f3bec76d1bd14ed11188877dd3039d0bcfd489 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Fri, 2 Oct 2009 01:32:00 -0700 Subject: 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(-) (limited to 'src') diff --git a/src/kern/operatingsystem.hh b/src/kern/operatingsystem.hh index 47e64ffd9..6574e3c6b 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 c9ce4b14f..e45a6c797 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. " -- cgit v1.2.3 From 44ceb80c2dd1c4991357292ca27809b5012b9556 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Fri, 2 Oct 2009 01:32:58 -0700 Subject: 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(-) (limited to 'src') diff --git a/src/arch/x86/linux/linux.hh b/src/arch/x86/linux/linux.hh index d5bead8f3..a810d4a79 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 4082e568c..f7678443d 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* -- cgit v1.2.3 From 8a761c44af607c1a05642d32cbaa6b97106e6b7d Mon Sep 17 00:00:00 2001 From: Steve Reinhardt Date: Sat, 3 Oct 2009 18:07:39 -0700 Subject: bus: add assertion to catch illegal retry on mem-inhibited transaction. --- src/mem/bus.cc | 3 +++ 1 file changed, 3 insertions(+) (limited to 'src') diff --git a/src/mem/bus.cc b/src/mem/bus.cc index 001c37a24..cac08d1a8 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); -- cgit v1.2.3 From 30a185dcd04cc7797609398219482d03a68509f9 Mon Sep 17 00:00:00 2001 From: Vince Weaver Date: Sat, 10 Oct 2009 22:31:56 -0700 Subject: 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(-) (limited to 'src') diff --git a/src/arch/x86/linux/syscalls.cc b/src/arch/x86/linux/syscalls.cc index 52352ee80..affe2d6ea 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), -- cgit v1.2.3 From 28204b2a964983738726428269e61833f4e1dce9 Mon Sep 17 00:00:00 2001 From: Brad Beckmann Date: Thu, 15 Oct 2009 15:15:24 -0700 Subject: 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(-) (limited to 'src') diff --git a/src/cpu/simple_thread.cc b/src/cpu/simple_thread.cc index 92c6ad69b..f18634198 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 b25b015d2..0bb6558c8 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) -- cgit v1.2.3 From 010b13c937c80b9138d5c70fda6c47ea75d2a9b3 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Sat, 17 Oct 2009 01:13:41 -0700 Subject: 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(-) (limited to 'src') diff --git a/src/arch/alpha/isa.cc b/src/arch/alpha/isa.cc index eee391a0d..8b6da3649 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 622d1da4c..574b50841 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 2315afa9e..9b21c03cd 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 15c043dc0..165adff83 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 f18634198..ad69719ee 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 -- cgit v1.2.3 From 22dc2b5595519d5fc7ca93854053b22a359e331b Mon Sep 17 00:00:00 2001 From: Vince Weaver Date: Fri, 16 Oct 2009 13:54:20 -0400 Subject: 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(-) (limited to 'src') diff --git a/src/arch/x86/linux/syscalls.cc b/src/arch/x86/linux/syscalls.cc index affe2d6ea..74a6ad0b7 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), -- cgit v1.2.3 From 56154cff5eab4a28a6d86a820a4364f99889555f Mon Sep 17 00:00:00 2001 From: Vince Weaver Date: Mon, 19 Oct 2009 17:29:34 -0400 Subject: 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(-) (limited to 'src') diff --git a/src/arch/x86/linux/syscalls.cc b/src/arch/x86/linux/syscalls.cc index 74a6ad0b7..2b54843f3 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), -- cgit v1.2.3 From 6c60db8ce99eabdbfcbe0f78a50817494142e39e Mon Sep 17 00:00:00 2001 From: "Timothy M. Jones" Date: Sat, 24 Oct 2009 10:53:57 -0700 Subject: syscall: Implementation of the times system call --- src/kern/linux/linux.hh | 11 +++++++++++ src/sim/syscall_emul.hh | 24 ++++++++++++++++++++++++ 2 files changed, 35 insertions(+) (limited to 'src') diff --git a/src/kern/linux/linux.hh b/src/kern/linux/linux.hh index 7c16228ea..2df323712 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 e45a6c797..ce7c7fa87 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; +} -- cgit v1.2.3 From 7cdd5316abaf91755edd9186d3836ff371902146 Mon Sep 17 00:00:00 2001 From: "Timothy M. Jones" Date: Sat, 24 Oct 2009 10:53:57 -0700 Subject: syscall: Implementation of the time system call. --- src/kern/linux/linux.hh | 1 + src/sim/syscall_emul.hh | 19 +++++++++++++++++++ 2 files changed, 20 insertions(+) (limited to 'src') diff --git a/src/kern/linux/linux.hh b/src/kern/linux/linux.hh index 2df323712..736213762 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 ce7c7fa87..6937e35f0 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__ -- cgit v1.2.3 From c32d919bc07d87e5fc59d98cb58e9143182c1aef Mon Sep 17 00:00:00 2001 From: "Timothy M. Jones" Date: Sat, 24 Oct 2009 10:53:58 -0700 Subject: syscall: Implementation of the ftruncate64 system call. --- src/sim/syscall_emul.cc | 16 ++++++++++++++++ src/sim/syscall_emul.hh | 5 +++++ 2 files changed, 21 insertions(+) (limited to 'src') diff --git a/src/sim/syscall_emul.cc b/src/sim/syscall_emul.cc index bd66594af..9a797bcdb 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 6937e35f0..f5e8a02e5 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); -- cgit v1.2.3 From cc21f862e2d6ad6ba8d5332d6bbc05e58e55bfa0 Mon Sep 17 00:00:00 2001 From: "Timothy M. Jones" Date: Sat, 24 Oct 2009 10:53:58 -0700 Subject: syscall: Fix conversion of the stat64 buffer during system calls. --- src/sim/syscall_emul.hh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/sim/syscall_emul.hh b/src/sim/syscall_emul.hh index f5e8a02e5..21f8201c8 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); } -- cgit v1.2.3 From 03da1e53c24aa86a3b04216c3d2d002fd9020ea0 Mon Sep 17 00:00:00 2001 From: "Timothy M. Jones" Date: Sat, 24 Oct 2009 10:53:58 -0700 Subject: 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(+) (limited to 'src') diff --git a/src/sim/syscall_emul.cc b/src/sim/syscall_emul.cc index 9a797bcdb..13ad04311 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); + } + } } } -- cgit v1.2.3 From 1b2d75d6d276f316b8c3f40fa93901ab6233128f Mon Sep 17 00:00:00 2001 From: "Timothy M. Jones" Date: Sat, 24 Oct 2009 10:53:59 -0700 Subject: 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(+) (limited to 'src') diff --git a/src/arch/alpha/linux/linux.hh b/src/arch/alpha/linux/linux.hh index e9947644c..c728ce1fb 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 4ba35fc50..0ee12973c 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 b9b10a593..f829dd7c6 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 b30cca2fb..a2418cfb6 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 21f8201c8..0c51c7dec 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: -- cgit v1.2.3 From 0fdfc82bde5b8975ee93d5da9c604ad9b99942e0 Mon Sep 17 00:00:00 2001 From: Brad Beckmann Date: Mon, 26 Oct 2009 17:06:32 -0700 Subject: 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(-) (limited to 'src') diff --git a/src/mem/slicc/ast/ChipComponentAccessAST.py b/src/mem/slicc/ast/ChipComponentAccessAST.py index 841220c94..bbb1b61e9 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 113bb188a..c62e28741 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 ecfe43cdb..d423ee4a7 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 1d08a7234..f1aff1c32 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 d068666ad..138fff793 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 285d5b622..a60153664 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 337b15597..2c8cf3f7b 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)) -- cgit v1.2.3 From 835a55e7f347697815fc43851b2dd5a8642d21c4 Mon Sep 17 00:00:00 2001 From: "Timothy M. Jones" Date: Tue, 27 Oct 2009 09:24:39 -0700 Subject: 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. --- 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 +- 62 files changed, 7462 insertions(+), 2 deletions(-) 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 (limited to 'src') diff --git a/src/arch/isa_parser.py b/src/arch/isa_parser.py index f001eff41..e3da240d2 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 000000000..36dff5333 --- /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 000000000..1fb36eaab --- /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 000000000..d762c2d58 --- /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 000000000..eadcb7900 --- /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 000000000..3f4346c97 --- /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 000000000..dd00e42c3 --- /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 000000000..0a942a982 --- /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 000000000..a23667d9e --- /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 000000000..f5c34ee2a --- /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 000000000..2b2668409 --- /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 000000000..1f81a15dc --- /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 000000000..b4b96d5dc --- /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 000000000..447efa2f4 --- /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 000000000..329dafe57 --- /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 000000000..913030b61 --- /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 000000000..dd4941b93 --- /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 000000000..1982744bf --- /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 000000000..399e75371 --- /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 000000000..ba1b5018d --- /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 000000000..8cd323ad5 --- /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 000000000..3252ff14a --- /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 000000000..adb5e7ef8 --- /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 000000000..d51ed5c25 --- /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 000000000..12ee7ae7d --- /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 000000000..ec2575196 --- /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 000000000..db917476e --- /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 000000000..0766826ec --- /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 000000000..1be49c2f7 --- /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 000000000..93536aa18 --- /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 000000000..60a7c469d --- /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 000000000..06e6ece26 --- /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 000000000..ab1e530b2 --- /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 000000000..47e8c1411 --- /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 000000000..cce7e39ee --- /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 000000000..fc6c32685 --- /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 000000000..886c2cb0b --- /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 000000000..113f3e48e --- /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 000000000..c681c8baf --- /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 000000000..b03ccfc8c --- /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 000000000..78b0eef7f --- /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 000000000..56ab1d4a0 --- /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 000000000..e35db5112 --- /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 000000000..cd9815b2a --- /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 000000000..bd1ea10b3 --- /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 000000000..862404578 --- /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 000000000..bd2b9d397 --- /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 000000000..1f3ac41cb --- /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 000000000..8828a1a93 --- /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 000000000..dae776c4c --- /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 000000000..5bcca3641 --- /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 000000000..34bb4bd1f --- /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 000000000..49d687a6e --- /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 000000000..125c92a1a --- /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 000000000..8b6c7233d --- /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 000000000..7b994adc9 --- /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 000000000..442075aa2 --- /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 000000000..3cfebcfc7 --- /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 15ad88f76..60f0f99b4 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 e511451b7..b08f1c633 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 75114053e..ac734e5ac 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 ec6ac0449..cf0f2b84d 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 -- cgit v1.2.3 From 776f9405fa0e58ea5ca0354cd233ebb2603bddbf Mon Sep 17 00:00:00 2001 From: Vince Weaver Date: Tue, 20 Oct 2009 15:15:37 -0400 Subject: 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(-) (limited to 'src') diff --git a/src/arch/x86/linux/linux.hh b/src/arch/x86/linux/linux.hh index a810d4a79..238b5e683 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[]; -- cgit v1.2.3 From 2b473cb099ad64030a103ee4292e2247f7a3e817 Mon Sep 17 00:00:00 2001 From: Vince Weaver Date: Tue, 20 Oct 2009 14:44:51 -0400 Subject: hook up stat64 syscall on 32-bit X86_SE --- src/arch/x86/linux/syscalls.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/arch/x86/linux/syscalls.cc b/src/arch/x86/linux/syscalls.cc index 2b54843f3..40f70c3fb 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), -- cgit v1.2.3 From 5b6f707a008b4312fd02a4383bf107adfa677d33 Mon Sep 17 00:00:00 2001 From: Vince Weaver Date: Tue, 20 Oct 2009 16:48:00 -0400 Subject: hook up stat syscall on 64-bit x86_SE --- src/arch/x86/linux/syscalls.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/arch/x86/linux/syscalls.cc b/src/arch/x86/linux/syscalls.cc index 40f70c3fb..14b3fa69b 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), -- cgit v1.2.3 From 14691148cd9300ed7a23dd889b9c0173124b30eb Mon Sep 17 00:00:00 2001 From: Vince Weaver Date: Wed, 21 Oct 2009 13:40:43 -0400 Subject: 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 ++-- .../insts/simd128/integer/data_transfer/move.py | 56 +++++++++++++++++++++- 2 files changed, 58 insertions(+), 6 deletions(-) (limited to 'src') diff --git a/src/arch/x86/isa/decoder/two_byte_opcodes.isa b/src/arch/x86/isa/decoder/two_byte_opcodes.isa index c23eeccab..27aabaccc 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 c34bd42bb..ec80ffe73 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 -- cgit v1.2.3 From 87b97f28bd2abc9feb352e7d3f0a85e9bc073912 Mon Sep 17 00:00:00 2001 From: Vince Weaver Date: Tue, 27 Oct 2009 14:11:06 -0400 Subject: Fix problem with the x86 sse movhpd instruction. The movhpd instruction was writing to the wrong memory offset. --- .../x86/isa/insts/simd128/floating_point/data_transfer/move.py | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) (limited to 'src') 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 1f4044bde..09b380fbd 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 { -- cgit v1.2.3 From f9624e49f6d37e42af63a4d7ca401103c67d8027 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Tue, 27 Oct 2009 23:50:25 -0700 Subject: X86: Replace "DISPLACEMENT" with disp in movhpd. --- .../x86/isa/insts/simd128/floating_point/data_transfer/move.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'src') 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 09b380fbd..ffe084786 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 { -- cgit v1.2.3 From 25d932868998db26054910078721433ab430c836 Mon Sep 17 00:00:00 2001 From: Nathan Binkert Date: Wed, 28 Oct 2009 11:56:56 -0700 Subject: 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 +++++++++++++++++++ .../network/garnet-fixed-pipeline/CreditLink_d.hh | 30 +++++++++++++++++++--- .../garnet-fixed-pipeline/GarnetNetwork_d.cc | 11 +++----- .../garnet-fixed-pipeline/GarnetNetwork_d.hh | 11 +++----- .../network/garnet-fixed-pipeline/InputUnit_d.cc | 11 +++----- .../network/garnet-fixed-pipeline/InputUnit_d.hh | 11 +++----- .../network/garnet-fixed-pipeline/NetworkHeader.hh | 11 +++----- .../garnet-fixed-pipeline/NetworkInterface_d.cc | 11 +++----- .../garnet-fixed-pipeline/NetworkInterface_d.hh | 11 +++----- .../network/garnet-fixed-pipeline/NetworkLink_d.cc | 11 +++----- .../network/garnet-fixed-pipeline/NetworkLink_d.hh | 11 +++----- .../network/garnet-fixed-pipeline/OutVcState_d.cc | 11 +++----- .../network/garnet-fixed-pipeline/OutVcState_d.hh | 11 +++----- .../network/garnet-fixed-pipeline/OutputUnit_d.cc | 11 +++----- .../network/garnet-fixed-pipeline/OutputUnit_d.hh | 11 +++----- .../ruby/network/garnet-fixed-pipeline/Router_d.cc | 11 +++----- .../ruby/network/garnet-fixed-pipeline/Router_d.hh | 10 +++----- .../network/garnet-fixed-pipeline/RoutingUnit_d.cc | 11 +++----- .../network/garnet-fixed-pipeline/RoutingUnit_d.hh | 11 +++----- .../network/garnet-fixed-pipeline/SWallocator_d.cc | 11 +++----- .../network/garnet-fixed-pipeline/SWallocator_d.hh | 11 +++----- .../ruby/network/garnet-fixed-pipeline/Switch_d.cc | 11 +++----- .../ruby/network/garnet-fixed-pipeline/Switch_d.hh | 11 +++----- .../network/garnet-fixed-pipeline/VCallocator_d.cc | 11 +++----- .../network/garnet-fixed-pipeline/VCallocator_d.hh | 11 +++----- .../garnet-fixed-pipeline/VirtualChannel_d.cc | 11 +++----- .../garnet-fixed-pipeline/VirtualChannel_d.hh | 11 +++----- .../network/garnet-fixed-pipeline/flitBuffer_d.cc | 11 +++----- .../network/garnet-fixed-pipeline/flitBuffer_d.hh | 11 +++----- .../ruby/network/garnet-fixed-pipeline/flit_d.cc | 11 +++----- .../ruby/network/garnet-fixed-pipeline/flit_d.hh | 12 +++------ .../garnet-flexible-pipeline/FlexibleConsumer.hh | 10 +++----- .../garnet-flexible-pipeline/GarnetNetwork.cc | 11 +++----- .../garnet-flexible-pipeline/GarnetNetwork.hh | 11 +++----- .../network/garnet-flexible-pipeline/InVcState.cc | 11 +++----- .../network/garnet-flexible-pipeline/InVcState.hh | 12 +++------ .../garnet-flexible-pipeline/NetworkConfig.hh | 14 +++++----- .../garnet-flexible-pipeline/NetworkInterface.cc | 11 +++----- .../garnet-flexible-pipeline/NetworkInterface.hh | 10 +++----- .../garnet-flexible-pipeline/NetworkLink.cc | 11 +++----- .../garnet-flexible-pipeline/NetworkLink.hh | 10 +++----- .../network/garnet-flexible-pipeline/OutVcState.cc | 11 +++----- .../network/garnet-flexible-pipeline/OutVcState.hh | 11 +++----- .../network/garnet-flexible-pipeline/Router.cc | 11 +++----- .../network/garnet-flexible-pipeline/Router.hh | 11 +++----- .../network/garnet-flexible-pipeline/VCarbiter.cc | 11 +++----- .../network/garnet-flexible-pipeline/VCarbiter.hh | 11 +++----- .../ruby/network/garnet-flexible-pipeline/flit.cc | 11 +++----- .../ruby/network/garnet-flexible-pipeline/flit.hh | 11 +++----- .../network/garnet-flexible-pipeline/flitBuffer.cc | 11 +++----- .../network/garnet-flexible-pipeline/flitBuffer.hh | 11 +++----- 51 files changed, 204 insertions(+), 393 deletions(-) (limited to 'src') diff --git a/src/mem/ruby/network/Network.cc b/src/mem/ruby/network/Network.cc index 984ec7ca8..ac785f632 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 387ed0bc1..c554d7216 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 51393b576..df643e800 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,14 +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. - */ - -/* - * GarnetNetwork_d.cc * - * Niket Agarwal, Princeton University - * - * */ + * Authors: Niket Agarwal + */ #include "mem/ruby/network/garnet-fixed-pipeline/GarnetNetwork_d.hh" #include "mem/protocol/MachineType.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 f4b809443..997f5e374 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,14 +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. - */ - -/* - * GarnetNetwork_d.hh * - * Niket Agarwal, Princeton University - * - * */ + * Authors: Niket Agarwal + */ #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 0ae32de13..7f344b0b7 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,14 +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. - */ - -/* - * InputUnit_d.C * - * Niket Agarwal, Princeton University - * - * */ + * Authors: Niket Agarwal + */ #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 a59ac89d8..beee79b3e 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,14 +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. - */ - -/* - * InputUnit_d.hh * - * Niket Agarwal, Princeton University - * - * */ + * Authors: Niket Agarwal + */ #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 a69dbf107..62ed9a12c 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,14 +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. - */ - -/* - * NetworkHeader.hh * - * Niket Agarwal, Princeton University - * - * */ + * Authors: Niket Agarwal + */ #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 3377ffd1d..c31b76d62 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,14 +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. - */ - -/* - * NetworkInterface_d.cc * - * Niket Agarwal, Princeton University - * - * */ + * Authors: Niket Agarwal + */ #include "mem/ruby/network/garnet-fixed-pipeline/NetworkInterface_d.hh" #include "mem/ruby/buffers/MessageBuffer.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 625226254..12b8d57e1 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,14 +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. - */ - -/* - * NetworkInterface_d.hh * - * Niket Agarwal, Princeton University - * - * */ + * Authors: Niket Agarwal + */ #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 8382d331f..dc3c73b0c 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,14 +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. - */ - -/* - * NetworkLink_d.cc * - * Niket Agarwal, Princeton University - * - * */ + * Authors: Niket Agarwal + */ #include "mem/ruby/network/garnet-fixed-pipeline/NetworkLink_d.hh" #include "mem/ruby/network/garnet-flexible-pipeline/NetworkConfig.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 90fb9f6dc..fed8afbd3 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,14 +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. - */ - -/* - * NetworkLink_d.hh * - * Niket Agarwal, Princeton University - * - * */ + * Authors: Niket Agarwal + */ #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 69e3ae377..42d9af861 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,14 +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. - */ - -/* - * OutVCState_d.cc * - * Niket Agarwal, Princeton University - * - * */ + * Authors: Niket Agarwal + */ #include "mem/ruby/network/garnet-fixed-pipeline/OutVcState_d.hh" #include "mem/ruby/network/garnet-flexible-pipeline/NetworkConfig.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 dc64b8504..fe6b5fc79 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,14 +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. - */ - -/* - * OutVCState_d.hh * - * Niket Agarwal, Princeton University - * - * */ + * Authors: Niket Agarwal + */ #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 eb2450897..e672009c9 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,14 +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. - */ - -/* - * OutputUnit_d.cc * - * Niket Agarwal, Princeton University - * - * */ + * Authors: Niket Agarwal + */ #include "mem/ruby/network/garnet-fixed-pipeline/OutputUnit_d.hh" #include "mem/ruby/network/garnet-fixed-pipeline/Router_d.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 78f46d1b5..beeab8c7f 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,14 +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. - */ - -/* - * OutputUnit_d.hh * - * Niket Agarwal, Princeton University - * - * */ + * Authors: Niket Agarwal + */ #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 161e6ecff..5334de7b9 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,14 +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. - */ - -/* - * Router_d.cc * - * Niket Agarwal, Princeton University - * - * */ + * Authors: Niket Agarwal + */ #include "mem/ruby/network/garnet-fixed-pipeline/Router_d.hh" #include "mem/ruby/network/garnet-fixed-pipeline/GarnetNetwork_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 23a8681d9..f9af1abfb 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 488741055..9f12ac9cc 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,14 +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. - */ - -/* - * Routingunit_d.C * - * Niket Agarwal, Princeton University - * - * */ + * Authors: Niket Agarwal + */ #include "mem/ruby/network/garnet-fixed-pipeline/RoutingUnit_d.hh" #include "mem/ruby/network/garnet-fixed-pipeline/Router_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 091ee90ef..33c9f3cc4 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,14 +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. - */ - -/* - * Routerunit_d.hh * - * Niket Agarwal, Princeton University - * - * */ + * Authors: Niket Agarwal + */ #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 dd0378305..c7308597a 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,14 +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. - */ - -/* - * SWallocator_d.cc * - * Niket Agarwal, Princeton University - * - * */ + * Authors: Niket Agarwal + */ #include "mem/ruby/network/garnet-fixed-pipeline/SWallocator_d.hh" #include "mem/ruby/network/garnet-fixed-pipeline/Router_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 b1867df7f..f0ec5d77e 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,14 +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. - */ - -/* - * SWallocator_d.hh * - * Niket Agarwal, Princeton University - * - * */ + * Authors: Niket Agarwal + */ #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 e1ca64864..11a196906 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,14 +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. - */ - -/* - * Switch_d.C * - * Niket Agarwal, Princeton University - * - * */ + * Authors: Niket Agarwal + */ #include "mem/ruby/network/garnet-fixed-pipeline/Switch_d.hh" #include "mem/ruby/network/garnet-fixed-pipeline/Router_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 2e2f524a0..936972714 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,14 +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. - */ - -/* - * Switch_d.hh * - * Niket Agarwal, Princeton University - * - * */ + * Authors: Niket Agarwal + */ #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 810aea175..4150907d1 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,14 +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. - */ - -/* - * VCallocator_d.cc * - * Niket Agarwal, Princeton University - * - * */ + * Authors: Niket Agarwal + */ #include "mem/ruby/network/garnet-flexible-pipeline/NetworkConfig.hh" #include "mem/ruby/network/garnet-fixed-pipeline/VCallocator_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 41e317bff..ad3c2c95f 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,14 +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. - */ - -/* - * VCallocator_d.hh * - * Niket Agarwal, Princeton University - * - * */ + * Authors: Niket Agarwal + */ #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 2e4473a29..5ce3ca4e5 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,14 +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. - */ - -/* - * VirtualChannel_d.C * - * Niket Agarwal, Princeton University - * - * */ + * Authors: Niket Agarwal + */ #include "mem/ruby/network/garnet-fixed-pipeline/VirtualChannel_d.hh" 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 4ac1898e2..2d81cb7e3 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,14 +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. - */ - -/* - * VirtualChannel_d.hh * - * Niket Agarwal, Princeton University - * - * */ + * Authors: Niket Agarwal + */ #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 f3ddca0f2..fa189a8cc 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,14 +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. - */ - -/* - * flitBuffer_d.C * - * Niket Agarwal, Princeton University - * - * */ + * Authors: Niket Agarwal + */ #include "mem/ruby/network/garnet-fixed-pipeline/flitBuffer_d.hh" 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 70a47d5f6..2edea9d76 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,14 +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. - */ - -/* - * flitBuffer_d.hh * - * Niket Agarwal, Princeton University - * - * */ + * Authors: Niket Agarwal + */ #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 3defb8029..15e0b0394 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,14 +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. - */ - -/* - * flit_d.C * - * Niket Agarwal, Princeton University - * - * */ + * Authors: Niket Agarwal + */ #include "mem/ruby/network/garnet-fixed-pipeline/flit_d.hh" 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 6f64f4940..39f04052d 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,15 +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. - */ - -/* - * flit_d.hh * - * Niket Agarwal, Princeton University - * - * */ - + * Authors: Niket Agarwal + */ #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 f8bf6b949..82179ec21 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 e56f5b5e8..5a6b610f9 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,14 +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. - */ - -/* - * GarnetNetwork.cc * - * Niket Agarwal, Princeton University - * - * */ + * Authors: Niket Agarwal + */ #include "mem/ruby/network/garnet-flexible-pipeline/GarnetNetwork.hh" #include "mem/protocol/MachineType.hh" diff --git a/src/mem/ruby/network/garnet-flexible-pipeline/GarnetNetwork.hh b/src/mem/ruby/network/garnet-flexible-pipeline/GarnetNetwork.hh index 194fef778..c0e4ac6e4 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,14 +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. - */ - -/* - * GarnetNetwork.hh * - * Niket Agarwal, Princeton University - * - * */ + * Authors: Niket Agarwal + */ #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 cecaf867e..7fdff46b9 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,14 +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. - */ - -/* - * InVCState.C * - * Niket Agarwal, Princeton University - * - * */ + * Authors: Niket Agarwal + */ #include "mem/ruby/network/garnet-flexible-pipeline/InVcState.hh" diff --git a/src/mem/ruby/network/garnet-flexible-pipeline/InVcState.hh b/src/mem/ruby/network/garnet-flexible-pipeline/InVcState.hh index b7005efea..67ff6b459 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,15 +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. - */ - -/* * - * InVCState.hh - * - * Niket Agarwal, Princeton University - * - * */ + * Authors: Niket Agarwal + */ #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 0a450c002..2080ef022 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 597c942b7..4af5b296f 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,14 +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. - */ - -/* - * NetworkInterface.cc * - * Niket Agarwal, Princeton University - * - * */ + * Authors: Niket Agarwal + */ #include "mem/ruby/network/garnet-flexible-pipeline/NetworkInterface.hh" #include "mem/ruby/buffers/MessageBuffer.hh" diff --git a/src/mem/ruby/network/garnet-flexible-pipeline/NetworkInterface.hh b/src/mem/ruby/network/garnet-flexible-pipeline/NetworkInterface.hh index af4b1d4eb..8444658ea 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 ddc92d44c..598c9e2a4 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,14 +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. - */ - -/* - * NetworkLink.cc * - * Niket Agarwal, Princeton University - * - * */ + * Authors: Niket Agarwal + */ #include "mem/ruby/network/garnet-flexible-pipeline/NetworkLink.hh" #include "mem/ruby/network/garnet-flexible-pipeline/NetworkConfig.hh" diff --git a/src/mem/ruby/network/garnet-flexible-pipeline/NetworkLink.hh b/src/mem/ruby/network/garnet-flexible-pipeline/NetworkLink.hh index 6cc35b39d..9f5640a2e 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 9a95971eb..a00dd19c1 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,14 +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. - */ - -/* - * OutVCState.C * - * Niket Agarwal, Princeton University - * - * */ + * Authors: Niket Agarwal + */ #include "mem/ruby/network/garnet-flexible-pipeline/OutVcState.hh" diff --git a/src/mem/ruby/network/garnet-flexible-pipeline/OutVcState.hh b/src/mem/ruby/network/garnet-flexible-pipeline/OutVcState.hh index cb05826dc..ba68bf2db 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,14 +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. - */ - -/* - * OutVCState.hh * - * Niket Agarwal, Princeton University - * - * */ + * Authors: Niket Agarwal + */ #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 ea32e938d..628f19349 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,14 +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. - */ - -/* - * Router.cc * - * Niket Agarwal, Princeton University - * - * */ + * Authors: Niket Agarwal + */ #include "mem/ruby/network/garnet-flexible-pipeline/Router.hh" #include "mem/ruby/slicc_interface/NetworkMessage.hh" diff --git a/src/mem/ruby/network/garnet-flexible-pipeline/Router.hh b/src/mem/ruby/network/garnet-flexible-pipeline/Router.hh index f3cf0036d..69d405ad4 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,14 +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. - */ - -/* - * Router.hh * - * Niket Agarwal, Princeton University - * - * */ + * Authors: Niket Agarwal + */ #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 271d6dd38..9064cc4a2 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,14 +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. - */ - -/* - * VCarbiter.C * - * Niket Agarwal, Princeton University - * - * */ + * Authors: Niket Agarwal + */ #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 96a03b8dc..7f7e5e814 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,14 +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. - */ - -/* - * VCarbiter.hh * - * Niket Agarwal, Princeton University - * - * */ + * Authors: Niket Agarwal + */ #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 51b8af6c6..549726348 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,14 +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. - */ - -/* - * flit.C * - * Niket Agarwal, Princeton University - * - * */ + * Authors: Niket Agarwal + */ #include "mem/ruby/network/garnet-flexible-pipeline/flit.hh" diff --git a/src/mem/ruby/network/garnet-flexible-pipeline/flit.hh b/src/mem/ruby/network/garnet-flexible-pipeline/flit.hh index aeac2e63b..a2e628443 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,14 +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. - */ - -/* - * flit.hh * - * Niket Agarwal, Princeton University - * - * */ + * Authors: Niket Agarwal + */ #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 a0bb71c9d..c68f8c78b 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,14 +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. - */ - -/* - * flitBuffer.C * - * Niket Agarwal, Princeton University - * - * */ + * Authors: Niket Agarwal + */ #include "mem/ruby/network/garnet-flexible-pipeline/flitBuffer.hh" diff --git a/src/mem/ruby/network/garnet-flexible-pipeline/flitBuffer.hh b/src/mem/ruby/network/garnet-flexible-pipeline/flitBuffer.hh index 006ba60bd..c722e161c 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,14 +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. - */ - -/* - * flitBuffer.hh * - * Niket Agarwal, Princeton University - * - * */ + * Authors: Niket Agarwal + */ #ifndef FLIT_BUFFER_H #define FLIT_BUFFER_H -- cgit v1.2.3 From 3f722b991fcb33ca21330501960406a8a58e2be2 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Fri, 30 Oct 2009 00:44:55 -0700 Subject: 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(-) (limited to 'src') diff --git a/src/arch/alpha/linux/process.cc b/src/arch/alpha/linux/process.cc index 0f09e472b..a653d7845 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 6aad45da8..9d75d5fa1 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 6d083c5ac..36b25a48e 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 8fa3cdeda..b039fbe19 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 a7f36e18d..f909d871a 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 53b3781d2..ab836fab2 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 cd7cc9736..702922a43 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 8954d3719..f793892d0 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 dde3a4efd..c2a05b73b 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 b9f608922..d96b0c81c 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 b8f4de20a..f35ec8554 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 b03ccfc8c..504d0e334 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 78b0eef7f..db6759a77 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 8828a1a93..92f993e4c 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 dae776c4c..ede75f05f 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 c50803976..874ddc005 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 89e853573..7e01f6b07 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 fdb9734ba..cca312e0a 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 eafb488df..24abd8687 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 14b3fa69b..4c29559fb 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 f7678443d..f7b3ce24a 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 cd6d99e66..4d031bd5a 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 c2bdd2776..033f30946 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 cf0f2b84d..e71d6441f 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 7922ce073..ab9d64cf3 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 13ad04311..d25f7b9fa 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 0c51c7dec..8fe53e266 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); -- cgit v1.2.3 From d6ff7929b30cde7bce1b3f3be89e1ef6eda82a2d Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Sat, 31 Oct 2009 13:20:22 -0700 Subject: Syscalls: Fix a warning turned error about an unused variable in m5.fast. --- src/sim/syscall_emul.cc | 2 ++ 1 file changed, 2 insertions(+) (limited to 'src') diff --git a/src/sim/syscall_emul.cc b/src/sim/syscall_emul.cc index d25f7b9fa..fae3586a4 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, -- cgit v1.2.3 From 9ad3acab5ea79effe27fba240d8f89aadc138f6f Mon Sep 17 00:00:00 2001 From: Vince Weaver Date: Fri, 30 Oct 2009 12:31:55 -0400 Subject: 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(+) (limited to 'src') diff --git a/src/sim/syscall_emul.cc b/src/sim/syscall_emul.cc index fae3586a4..cc8d99bcd 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 8fe53e266..27c26afb0 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); -- cgit v1.2.3 From cf269025f9e51eebb56d04fea6994fd72b1be4f9 Mon Sep 17 00:00:00 2001 From: Vince Weaver Date: Fri, 30 Oct 2009 12:51:13 -0400 Subject: 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(-) (limited to 'src') diff --git a/src/arch/x86/linux/syscalls.cc b/src/arch/x86/linux/syscalls.cc index 4c29559fb..2a7fd8d4e 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), -- cgit v1.2.3 From b2067840a6ad7e70495ad4dc6c74bf080e68133f Mon Sep 17 00:00:00 2001 From: Vince Weaver Date: Fri, 30 Oct 2009 14:19:06 -0400 Subject: 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(-) (limited to 'src') diff --git a/src/arch/x86/isa/decoder/two_byte_opcodes.isa b/src/arch/x86/isa/decoder/two_byte_opcodes.isa index 27aabaccc..5512f417c 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 8b307d3da..adf7650b9 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 +}; ''' -- cgit v1.2.3 From 5873ec2238e521f34f7e70e6aa1b35a611225d80 Mon Sep 17 00:00:00 2001 From: Vince Weaver Date: Fri, 30 Oct 2009 15:52:33 -0400 Subject: 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 +-- .../insts/general_purpose/data_transfer/move.py | 30 ++++++++++++++++++++++ 2 files changed, 32 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/arch/x86/isa/decoder/two_byte_opcodes.isa b/src/arch/x86/isa/decoder/two_byte_opcodes.isa index 5512f417c..d52dfb26e 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 7ccdca6c3..7aee3fec1 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): -- cgit v1.2.3 From a12557439ba0297fefb558b34ecc761d2bc34017 Mon Sep 17 00:00:00 2001 From: Vince Weaver Date: Fri, 30 Oct 2009 12:49:37 -0400 Subject: 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 +-- .../simd128/integer/shift/left_logical_shift.py | 40 +++++++++++++++++++++- .../simd128/integer/shift/right_logical_shift.py | 38 +++++++++++++++++++- 3 files changed, 78 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/arch/x86/isa/decoder/two_byte_opcodes.isa b/src/arch/x86/isa/decoder/two_byte_opcodes.isa index d52dfb26e..288c5e5a8 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 617033bc0..c13c7064c 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 c904eaf50..61efe1a5d 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 -- cgit v1.2.3 From 9b0a747dd41d3383769be1cd737733902875a528 Mon Sep 17 00:00:00 2001 From: Vince Weaver Date: Wed, 4 Nov 2009 00:19:15 -0500 Subject: 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(-) (limited to 'src') diff --git a/src/arch/x86/linux/syscalls.cc b/src/arch/x86/linux/syscalls.cc index 2a7fd8d4e..6a659108f 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), -- cgit v1.2.3 From a1042db29098da395d0de96c652c41904feb425a Mon Sep 17 00:00:00 2001 From: Vince Weaver Date: Wed, 4 Nov 2009 00:47:12 -0500 Subject: 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(+) (limited to 'src') diff --git a/src/arch/x86/process.cc b/src/arch/x86/process.cc index f7b3ce24a..7cc889d7c 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 4d031bd5a..3ad2abe08 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(); -- cgit v1.2.3 From fbfe92b5b8f4bfe229632d6d34e8ecb4dc7c1b29 Mon Sep 17 00:00:00 2001 From: Steve Reinhardt Date: Wed, 4 Nov 2009 14:23:25 -0800 Subject: 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(-) (limited to 'src') diff --git a/src/cpu/o3/cpu.cc b/src/cpu/o3/cpu.cc index de1e24201..2a4e0176a 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 65170d8b2..2ea918983 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 695b3b91a..78b266014 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; } -- cgit v1.2.3 From 2c5fe6f95e64a5a97d56cccc6b8b5417cdd981ae Mon Sep 17 00:00:00 2001 From: Nathan Binkert Date: Wed, 4 Nov 2009 16:57:01 -0800 Subject: 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(-) (limited to 'src') diff --git a/src/arch/arm/insts/static_inst.cc b/src/arch/arm/insts/static_inst.cc index df2d5de25..5181041d0 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 6e4f7afea..b8b02ae9e 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 1b7933036..1b83c6649 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 06a656efc..47d24ed1e 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 1594cc375..31183f2f9 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 ce9942c9c..d741e1f7b 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 d60684231..a4e8738d3 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 898a189ef..1a280e993 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 c54379c23..68747b3d1 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 1a6db9fbb..0c10fac64 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 7935e5517..605b7f690 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 21e04ed25..b5feaf584 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 f1980c713..1390d0807 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 4543dd07b..40f856d8a 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 ed936d0cb..591fee6a4 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 abe7c0b75..72f1832b8 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 be4086cd9..121a6e447 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 c48152354..88cd2668a 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 bc69c3cc7..358e13c6f 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 29efdeb6f..92c38142c 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 e71d6441f..343d2ad5a 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 cc8d99bcd..7cffffcf1 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" -- cgit v1.2.3 From 058ccfc7fe7be1b7b7124ecdd0d9d79fe4d6a86f Mon Sep 17 00:00:00 2001 From: Steve Reinhardt Date: Thu, 5 Nov 2009 11:11:05 -0800 Subject: slicc: whack some of Nate's leftover debug code --- src/mem/protocol/SConscript | 3 --- 1 file changed, 3 deletions(-) (limited to 'src') diff --git a/src/mem/protocol/SConscript b/src/mem/protocol/SConscript index 425219580..948fd6c1a 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): -- cgit v1.2.3 From 9098010e3fccf779786c7f0e1dfab9d522f72eb5 Mon Sep 17 00:00:00 2001 From: Steve Reinhardt Date: Thu, 5 Nov 2009 11:11:06 -0800 Subject: 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(-) (limited to 'src') diff --git a/src/mem/protocol/SConscript b/src/mem/protocol/SConscript index 948fd6c1a..cd9920d22 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 2303725a3..1adb31321 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 42f98afc7..36c520070 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 c16fc8a75..a20f4b749 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 7ff3bf8a7..980804c2a 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 8d48ccbf5..ee75b6d6a 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 d2cc04eff..ecdb5949b 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 0bc2ef37a..f8efcc323 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 0e5ccc885..6c3f45629 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 ' -- cgit v1.2.3 From 5cf2e7ccf027a485c2e2eb9a60b70c3b45853f0c Mon Sep 17 00:00:00 2001 From: Vince Weaver Date: Wed, 4 Nov 2009 13:22:15 -0500 Subject: 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. --- .../x86/isa/insts/simd128/floating_point/data_transfer/move.py | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) (limited to 'src') 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 ffe084786..86ac89ade 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 { -- cgit v1.2.3 From 18b21c1ecaf7858c592c56cf4c12ec8781f821ba Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Sat, 7 Nov 2009 22:34:33 -0800 Subject: ARM: Get rid of some unneeded register indexes. --- src/arch/arm/registers.hh | 30 ------------------------------ 1 file changed, 30 deletions(-) (limited to 'src') diff --git a/src/arch/arm/registers.hh b/src/arch/arm/registers.hh index 7f9b6b828..07af32c1e 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 -- cgit v1.2.3 From 4a454c4f47362bd6f842fe1919f959a672ab1bb4 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Sun, 8 Nov 2009 00:07:35 -0800 Subject: 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 (limited to 'src') diff --git a/src/arch/arm/intregs.hh b/src/arch/arm/intregs.hh new file mode 100644 index 000000000..191965c55 --- /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 355a67ea9..d978967ac 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: ARM: Implement the shadow registers using register flattening. --- src/arch/arm/isa.hh | 43 +++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 41 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/arch/arm/isa.hh b/src/arch/arm/isa.hh index 9b21c03cd..1ad5428e5 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 -- cgit v1.2.3 From 43e9209c218daf506b6c2580e689e297c48e8f48 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Sun, 8 Nov 2009 00:54:32 -0800 Subject: 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(-) (limited to 'src') diff --git a/src/arch/arm/isa.hh b/src/arch/arm/isa.hh index 1ad5428e5..6341e6cd0 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. -- cgit v1.2.3 From f63c260d89591d8d57274bb37aea51dc7c093b8f Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Sun, 8 Nov 2009 01:57:34 -0800 Subject: ARM: Get rid of the Raddr operand. --- src/arch/arm/isa/operands.isa | 1 - 1 file changed, 1 deletion(-) (limited to 'src') diff --git a/src/arch/arm/isa/operands.isa b/src/arch/arm/isa/operands.isa index ac7427dad..a4c404bd5 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), -- cgit v1.2.3 From 78bd8fe44fe3398f361335d2feb59a8221cc52e8 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Sun, 8 Nov 2009 01:59:20 -0800 Subject: 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(-) (limited to 'src') diff --git a/src/arch/arm/intregs.hh b/src/arch/arm/intregs.hh index 191965c55..78ad39ee2 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 a4c404bd5..4ac6790e5 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), -- cgit v1.2.3 From 3a3e8461511663a3154d0507ba1b0f52ea5366c5 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Sun, 8 Nov 2009 02:00:55 -0800 Subject: 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(-) (limited to 'src') diff --git a/src/arch/arm/registers.hh b/src/arch/arm/registers.hh index 04fd00f3a..41bbf4e7f 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; -- cgit v1.2.3 From d188821d3700ee42e01fc43c9ef17568991fb3ff Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Sun, 8 Nov 2009 02:01:02 -0800 Subject: 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(+) (limited to 'src') diff --git a/src/arch/arm/isa.hh b/src/arch/arm/isa.hh index 6341e6cd0..f8359679b 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 3180669de..ba394d49c 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 2c4e1291c..d5cc07eaf 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 -- cgit v1.2.3 From 48525f581c6233b8f7a8a872c5774d4e245f431c Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Sun, 8 Nov 2009 02:08:40 -0800 Subject: 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(-) (limited to 'src') diff --git a/src/arch/arm/intregs.hh b/src/arch/arm/intregs.hh index 78ad39ee2..b5f955c4b 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 a999b52e9..ebadeb985 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 95f4f14e1..5f1b541ff 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 e88531580..e79529615 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 e90788c91..3c97560fd 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 b5efec568..d42ffb147 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 4ac6790e5..02acc8ed7 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 1ad9e1a19..01f3205eb 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]); } -- cgit v1.2.3 From 708faa767763e65a2fded8aa33ac3c63cca9c84c Mon Sep 17 00:00:00 2001 From: Nathan Binkert Date: Sun, 8 Nov 2009 13:31:59 -0800 Subject: 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(-) (limited to 'src') diff --git a/src/arch/isa_parser.py b/src/arch/isa_parser.py index e3da240d2..2db7c6aa6 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 7cc889d7c..42ca7b27d 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; -- cgit v1.2.3 From bb903b6514b743e93e429929776639879d6c59a7 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Sun, 8 Nov 2009 15:16:59 -0800 Subject: 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(-) (limited to 'src') diff --git a/src/arch/arm/isa/formats/macromem.isa b/src/arch/arm/isa/formats/macromem.isa index d978967ac..8c8ba8a1a 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(); } }}; -- cgit v1.2.3 From 8a4af3668dd8c45de4b98f3eb1fb2ef28bd369a2 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Sun, 8 Nov 2009 15:49:03 -0800 Subject: 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(-) (limited to 'src') diff --git a/src/arch/arm/insts/macromem.hh b/src/arch/arm/insts/macromem.hh index 541c9e3f5..714b8bb7e 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 b5f955c4b..0c2fc5fbb 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 f8359679b..a4a328614 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 8c8ba8a1a..9a3185af3 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 { -- cgit v1.2.3 From 374d337693a53c7c7096b55537b20980a29a3e74 Mon Sep 17 00:00:00 2001 From: Steve Reinhardt Date: Sun, 8 Nov 2009 17:35:49 -0800 Subject: scons: deal with generated .py files properly --- src/SConscript | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) (limited to 'src') diff --git a/src/SConscript b/src/SConscript index 35753ce4c..d02d2a6e7 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 -- cgit v1.2.3 From 53086dfefe2796497724daaa7d5d1d3d85a8a636 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Sun, 8 Nov 2009 22:49:57 -0800 Subject: X86: Make x86 use PREFETCH instead of PF_EXCLUSIVE. --- src/arch/x86/isa/microops/ldstop.isa | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/arch/x86/isa/microops/ldstop.isa b/src/arch/x86/isa/microops/ldstop.isa index 912aa3511..afe1ead59 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)" -- cgit v1.2.3 From 44e912c6bd8828a6a3774c1fa54a1f4689383243 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Sun, 8 Nov 2009 22:49:57 -0800 Subject: 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(-) (limited to 'src') diff --git a/src/arch/x86/tlb.cc b/src/arch/x86/tlb.cc index 5280b9ba8..0d69d05c9 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, -- cgit v1.2.3 From bbbfdee2ed4feb5e8e448920e5d51701a2192ee1 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Sun, 8 Nov 2009 22:49:58 -0800 Subject: X86: Don't panic on faults on prefetches in SE mode. --- src/arch/x86/tlb.cc | 26 +++++++++++++++----------- 1 file changed, 15 insertions(+), 11 deletions(-) (limited to 'src') diff --git a/src/arch/x86/tlb.cc b/src/arch/x86/tlb.cc index 0d69d05c9..d7959da2c 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, -- cgit v1.2.3 From 7da221ca82e5e64b98d9e86421fa653e2ad3e540 Mon Sep 17 00:00:00 2001 From: Vince Weaver Date: Mon, 9 Nov 2009 10:02:55 -0500 Subject: 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(-) (limited to 'src') diff --git a/src/sim/syscall_emul.cc b/src/sim/syscall_emul.cc index 7cffffcf1..4461e8b52 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); -- cgit v1.2.3 From e81cc233a6fa82d2aec45bd9160db15df112f584 Mon Sep 17 00:00:00 2001 From: Vince Weaver Date: Tue, 10 Nov 2009 11:18:23 -0500 Subject: 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(-) (limited to 'src') diff --git a/src/arch/x86/isa/microops/mediaop.isa b/src/arch/x86/isa/microops/mediaop.isa index 9c53fa0fb..fa32583b0 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; } -- cgit v1.2.3 From 53e27c0277a41ab1cae45d82fb4409f65cf660c3 Mon Sep 17 00:00:00 2001 From: Vince Weaver Date: Tue, 10 Nov 2009 11:29:30 -0500 Subject: 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(-) (limited to 'src') 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 7aee3fec1..51f5ad23b 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 { -- cgit v1.2.3 From 4779020e139c70355335729b504195a0e5009e7a Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Tue, 10 Nov 2009 20:19:55 -0800 Subject: 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(-) (limited to 'src') diff --git a/src/arch/arm/intregs.hh b/src/arch/arm/intregs.hh index 0c2fc5fbb..15499601a 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); } } -- cgit v1.2.3 From 2e28da5583814efe1e0a09718f6a674f983d12d1 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Tue, 10 Nov 2009 20:34:38 -0800 Subject: 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 | 534 +++++---------------------------- src/arch/arm/faults.hh | 557 +++-------------------------------- 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, 188 insertions(+), 975 deletions(-) create mode 100644 src/arch/arm/utility.cc (limited to 'src') diff --git a/src/arch/arm/SConscript b/src/arch/arm/SConscript index 55ecabdc3..f5fe1727c 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 3d882c97f..b7dd2d503 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; - -FaultName ReservedInstructionFault::_name = "Reserved Instruction Fault"; -FaultVect ReservedInstructionFault::_vect = 0x0180; -FaultStat ReservedInstructionFault::_count; - -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) -{ - tc->setPC(HandlerBase); - tc->setNextPC(HandlerBase+sizeof(MachInst)); - tc->setNextNPC(HandlerBase+2*sizeof(MachInst)); -} - -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) +Addr +ArmFaultBase::getVector(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); + // ARM ARM B1-3 + 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; - // 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 - // 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 +ArmFaultBase::invoke(ThreadContext *tc) +{ + // 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 ); } +#endif // FULL_SYSTEM -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); +// return via SUBS pc, lr, xxx; rfe, movs, ldm - 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 28ecd7591..7f8aa66b6 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;} - public: - Addr BadVAddr; - Addr EntryHi_Asid; - Addr EntryHi_VPN2; - Addr EntryHi_VPN2X; - Addr Context_BadVPN2; -#if FULL_SYSTEM - void invoke(ThreadContext * tc) {}; - void setExceptionState(ThreadContext *,uint8_t); - void setHandlerPC(Addr,ThreadContext *); -#endif - virtual FaultVect vect() = 0; - virtual FaultStat & countStat() = 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;} -}; + Addr getVector(ThreadContext *tc); -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); -}; + 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; + }; - -class ArithmeticFault : public ArmFault -{ - protected: - bool skipFaultingInstruction() {return true;} - 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); + void invoke(ThreadContext *tc); #endif + 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 InterruptFault : public ArmFault +template +class ArmFault : public ArmFaultBase { 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 - - //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 - -}; + static FaultVals vals; -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 - + 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 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 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 {}; -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 a4a328614..a270f046b 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 c82bb41c6..6909c3f85 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 2ad7a2506..97a0caa6b 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 542174b6b..91c51c46b 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 ba394d49c..45233a764 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 000000000..8cfa48e18 --- /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); +} + -- cgit v1.2.3 From b8120f6c38f212acbfd246a3081842a9e3d06eb3 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Tue, 10 Nov 2009 21:10:18 -0800 Subject: 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(-) (limited to 'src') diff --git a/src/arch/alpha/faults.cc b/src/arch/alpha/faults.cc index e93e16711..ff6de8d03 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 cb43fcb74..52e124ad5 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 fedfbf55d..b1703221f 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 adcb16137..161a52b06 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 7dacc58ff..16b779e06 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 cd4f5457e..c092b5b1f 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 8d3bae3f6..6b22d2fcf 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 c8c31ffcd..f2cc4647c 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 */ -- cgit v1.2.3 From 5524af83efab8ee502f84987d56306ecd140ab80 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Tue, 10 Nov 2009 23:44:05 -0800 Subject: 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(-) (limited to 'src') diff --git a/src/arch/arm/isa/bitfields.isa b/src/arch/arm/isa/bitfields.isa index 5785939cc..fc75ecf79 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 ebadeb985..b4b820b06 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 3c97560fd..0d6ee32f7 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 02acc8ed7..5ae0b8912 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 d5cc07eaf..237bf8412 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; -- cgit v1.2.3 From 8f6744c19c7d6cf87a207e901503c3435c1ff7a9 Mon Sep 17 00:00:00 2001 From: Vince Weaver Date: Wed, 11 Nov 2009 17:49:09 -0500 Subject: 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(-) (limited to 'src') diff --git a/src/arch/x86/isa/microops/mediaop.isa b/src/arch/x86/isa/microops/mediaop.isa index fa32583b0..4052f254d 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 fd1ad6925..0b1f9a96a 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); -- cgit v1.2.3 From 48bc573f5f9709480da458e3c4627f7b7afd38f4 Mon Sep 17 00:00:00 2001 From: Ali Saidi Date: Sat, 14 Nov 2009 11:25:00 -0600 Subject: 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(-) (limited to 'src') diff --git a/src/arch/arm/isa/bitfields.isa b/src/arch/arm/isa/bitfields.isa index fc75ecf79..816cd4b6d 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 b4b820b06..20b544a7c 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(); } - } - } - } - 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; }}); - } + } // 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); } - 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 237bf8412..e37fd3a1f 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; -- cgit v1.2.3 From 4e9ce1805e3bbc6a6085502e94e0298eada77113 Mon Sep 17 00:00:00 2001 From: Ali Saidi Date: Sat, 14 Nov 2009 11:49:01 -0600 Subject: 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(-) (limited to 'src') diff --git a/src/kern/linux/linux.hh b/src/kern/linux/linux.hh index 736213762..7fe107139 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 4461e8b52..4726decc5 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 27c26afb0..66e800183 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; -- cgit v1.2.3 From 50b9149c7572b4cff351f2c28726226030cefdbd Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Sat, 14 Nov 2009 19:22:29 -0800 Subject: 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(-) (limited to 'src') diff --git a/src/arch/arm/isa.hh b/src/arch/arm/isa.hh index a270f046b..905eb0183 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 5ae0b8912..fe085cdac 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) }}; -- cgit v1.2.3 From 1df0025e28d8f9699f86fc118db3b93a0f1ec50c Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Sat, 14 Nov 2009 19:22:29 -0800 Subject: 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(-) (limited to 'src') diff --git a/src/arch/arm/isa/operands.isa b/src/arch/arm/isa/operands.isa index fe085cdac..aadefc79c 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) -- cgit v1.2.3 From 812e390693253818c49585daf35692759a1c82d4 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Sat, 14 Nov 2009 19:22:29 -0800 Subject: ARM: Fix up the implmentation of the mrs instruction. --- src/arch/arm/isa/decoder.isa | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/arch/arm/isa/decoder.isa b/src/arch/arm/isa/decoder.isa index 20b544a7c..cd13fa420 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 { -- cgit v1.2.3 From e543f162475b93a1cae7f301a7edd76067d81ba7 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Sat, 14 Nov 2009 19:22:30 -0800 Subject: 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(+) (limited to 'src') diff --git a/src/arch/arm/insts/static_inst.hh b/src/arch/arm/insts/static_inst.hh index c963c1827..f2881c3b6 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)); + } }; } -- cgit v1.2.3 From 425ebf6bd736d6a7172476a81e935c7b83467dc9 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Sat, 14 Nov 2009 19:22:30 -0800 Subject: 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(+) (limited to 'src') diff --git a/src/arch/arm/isa/bitfields.isa b/src/arch/arm/isa/bitfields.isa index 816cd4b6d..bd4cfc320 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 e37fd3a1f..07fa33ea1 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; -- cgit v1.2.3 From e2ab64543b2a206c95fbf38565a50f0d5bba0f2a Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Sat, 14 Nov 2009 19:22:30 -0800 Subject: ARM: Define a mask to differentiate purely CPSR bits from CondCodes bits. --- src/arch/arm/miscregs.hh | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'src') diff --git a/src/arch/arm/miscregs.hh b/src/arch/arm/miscregs.hh index 45233a764..d100efb8e 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 -- cgit v1.2.3 From c4042985d7b13ddd6afdd3748e9c619863f1233a Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Sat, 14 Nov 2009 19:22:30 -0800 Subject: ARM: Fix up the implmentation of the msr instruction. --- src/arch/arm/isa/decoder.isa | 37 +++++++++++++++++++++++++++---------- 1 file changed, 27 insertions(+), 10 deletions(-) (limited to 'src') diff --git a/src/arch/arm/isa/decoder.isa b/src/arch/arm/isa/decoder.isa index cd13fa420..5e82feb1b 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({{ }}); -- cgit v1.2.3 From b41725f7234e17d6d66d697ef415a4cb1bae80d9 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Sat, 14 Nov 2009 21:03:10 -0800 Subject: 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 | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) (limited to 'src') diff --git a/src/arch/arm/isa/decoder.isa b/src/arch/arm/isa/decoder.isa index 5e82feb1b..27af81382 100644 --- a/src/arch/arm/isa/decoder.isa +++ b/src/arch/arm/isa/decoder.isa @@ -115,17 +115,17 @@ format DataOp { }}); 0x9: decode USEIMM { // The mask field is the same as the RN index. - 0: PredImmOp::msr_cpsr_imm({{ + 0: PredOp::msr_cpsr_reg({{ uint32_t newCpsr = cpsrWriteByInstr(Cpsr | CondCodes, - rotated_imm, RN, false); + Rm, RN, false); Cpsr = ~CondCodesMask & newCpsr; CondCodes = CondCodesMask & newCpsr; }}); - 1: PredOp::msr_cpsr_reg({{ + 1: PredImmOp::msr_cpsr_imm({{ uint32_t newCpsr = cpsrWriteByInstr(Cpsr | CondCodes, - Rm, RN, false); + rotated_imm, RN, false); Cpsr = ~CondCodesMask & newCpsr; CondCodes = CondCodesMask & newCpsr; }}); @@ -133,13 +133,13 @@ format DataOp { 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 { -- cgit v1.2.3 From 903fb8c73df6feec125204fb4e636468f17b5eec Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Sun, 15 Nov 2009 00:15:42 -0800 Subject: 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(+) (limited to 'src') diff --git a/src/arch/arm/isa/formats/macromem.isa b/src/arch/arm/isa/formats/macromem.isa index 9a3185af3..ad27b5a56 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) }}; -- cgit v1.2.3 From 9127ee5ac8913eacfc62967bd4b275a1845d8a9b Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Sun, 15 Nov 2009 00:23:14 -0800 Subject: 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(-) (limited to 'src') diff --git a/src/arch/arm/isa/formats/macromem.isa b/src/arch/arm/isa/formats/macromem.isa index ad27b5a56..068b48199 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); -- cgit v1.2.3 From 171e7f7b24eead1fa82202549e3fad9a0df7b017 Mon Sep 17 00:00:00 2001 From: Ali Saidi Date: Mon, 16 Nov 2009 11:37:03 -0600 Subject: imported patch isa_fixes2.diff --- src/arch/arm/isa/decoder.isa | 30 +++++++++++++++++++----------- 1 file changed, 19 insertions(+), 11 deletions(-) (limited to 'src') diff --git a/src/arch/arm/isa/decoder.isa b/src/arch/arm/isa/decoder.isa index 27af81382..5a6e8773a 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); -- cgit v1.2.3 From 1470dae8e949eaef8232dc621d9074329357265c Mon Sep 17 00:00:00 2001 From: Ali Saidi Date: Tue, 17 Nov 2009 18:02:08 -0600 Subject: 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 --- 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 ++++++++++++++++++++++++++++++ 17 files changed, 936 insertions(+), 18 deletions(-) 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 (limited to 'src') diff --git a/src/arch/arm/ArmInterrupts.py b/src/arch/arm/ArmInterrupts.py new file mode 100644 index 000000000..f21d49e95 --- /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 000000000..872776c69 --- /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 f5fe1727c..92a4193f1 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 000000000..a47ebc75d --- /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 000000000..189341d6b --- /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 000000000..18bdc500d --- /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 000000000..6b346b0ab --- /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 c5225455c..05fdb9e78 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 000000000..e7470f89a --- /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 000000000..9dfb66fb7 --- /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 febc6d081..864c061a2 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 8cfa48e18..afff97d31 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 a2f0ef170..43e7b14ab 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 000000000..dd1d73e1a --- /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 000000000..7f36bbcf3 --- /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 000000000..7d571db99 --- /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 000000000..edec3631c --- /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__ -- cgit v1.2.3 From 0916c376a97dacf5d11589cfea084f0e7feda4cf Mon Sep 17 00:00:00 2001 From: Ali Saidi Date: Tue, 17 Nov 2009 18:02:08 -0600 Subject: 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(-) (limited to 'src') diff --git a/src/arch/arm/isa/formats/macromem.isa b/src/arch/arm/isa/formats/macromem.isa index 068b48199..c834c22cb 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); -- cgit v1.2.3 From 422f0d9f10c6c3899be5992f9e5555598d4de0d2 Mon Sep 17 00:00:00 2001 From: Ali Saidi Date: Tue, 17 Nov 2009 18:02:09 -0600 Subject: 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(-) (limited to 'src') diff --git a/src/arch/arm/insts/static_inst.cc b/src/arch/arm/insts/static_inst.cc index 5181041d0..bf7a38c58 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 bd4cfc320..8ff819983 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 5a6e8773a..ff20c6107 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 07fa33ea1..e0b3951b9 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 afff97d31..5ce32542b 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 43e7b14ab..3ddfd12dd 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); }; -- cgit v1.2.3 From 5492f71755d71ba47f3510e51510b1bbe96b743a Mon Sep 17 00:00:00 2001 From: Brad Beckmann Date: Wed, 18 Nov 2009 13:55:57 -0800 Subject: 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(-) (limited to 'src') diff --git a/src/mem/ruby/common/Debug.cc b/src/mem/ruby/common/Debug.cc index 1115152f4..cb9fdf082 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: 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(-) (limited to 'src') diff --git a/src/mem/ruby/common/DataBlock.hh b/src/mem/ruby/common/DataBlock.hh index 3c8ef56f4..1d399753e 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 1dcee7b7a..7301409ce 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 497c602d1..1a45340ed 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 2fb529e12..14b2048a0 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 e33418a42..1bfb135e8 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; -- cgit v1.2.3 From 17e14efa7e7358f02f2664e10e4001faf6b7811e Mon Sep 17 00:00:00 2001 From: Brad Beckmann Date: Wed, 18 Nov 2009 13:55:57 -0800 Subject: 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(-) (limited to 'src') diff --git a/src/mem/ruby/libruby.cc b/src/mem/ruby/libruby.cc index e4e302eba..b9a72d071 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 a73ff5cf4..29aac232a 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 780c1128e..c693e0f37 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 2b1f023c5..cf12c2a0b 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 -- cgit v1.2.3 From d7a4f665ed72b221e8210cc79bbd8edf967a4a4a Mon Sep 17 00:00:00 2001 From: Brad Beckmann Date: Wed, 18 Nov 2009 13:55:57 -0800 Subject: ruby: Added more info to bridge error message --- src/mem/bridge.cc | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/mem/bridge.cc b/src/mem/bridge.cc index cc9b83d3e..d0135fc9d 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 -- cgit v1.2.3 From 3cf24f9716eebab8c24fa645d02c636584033514 Mon Sep 17 00:00:00 2001 From: Brad Beckmann Date: Wed, 18 Nov 2009 13:55:58 -0800 Subject: 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. --- 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 ++- 6 files changed, 212 insertions(+), 39 deletions(-) (limited to 'src') diff --git a/src/mem/RubyMemory.py b/src/mem/RubyMemory.py index fbbbeebe4..ddd97572c 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 21335a709..2188850e0 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 2b416e647..b7842aaaf 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 38ef09177..1d36de878 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 14b2048a0..70077e7da 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 1bfb135e8..dd0a492f5 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); -- cgit v1.2.3 From dce53610c374eba2a8dae236a13b3197cd42edc6 Mon Sep 17 00:00:00 2001 From: Brad Beckmann Date: Wed, 18 Nov 2009 13:55:58 -0800 Subject: ruby: Added error check for openning the ruby config file --- src/mem/rubymem.cc | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'src') diff --git a/src/mem/rubymem.cc b/src/mem/rubymem.cc index 70077e7da..aecc0af32 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]; -- cgit v1.2.3 From 90d6e2652fc8590116d436a1143700e11893cfa4 Mon Sep 17 00:00:00 2001 From: Brad Beckmann Date: Wed, 18 Nov 2009 13:55:58 -0800 Subject: 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. --- src/mem/RubyMemory.py | 1 + src/mem/rubymem.cc | 10 ++++++---- src/mem/rubymem.hh | 1 + 3 files changed, 8 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/mem/RubyMemory.py b/src/mem/RubyMemory.py index ddd97572c..2ad794a3f 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 aecc0af32..9a1a7927d 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 dd0a492f5..2672dcb77 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; -- cgit v1.2.3 From 6e1dc2546cfe0c6da08b57cd8478c28820277890 Mon Sep 17 00:00:00 2001 From: Brad Beckmann Date: Wed, 18 Nov 2009 13:55:58 -0800 Subject: m5: Added isValidSrc and isValidDest calls to packet.hh --- src/mem/packet.hh | 2 ++ 1 file changed, 2 insertions(+) (limited to 'src') diff --git a/src/mem/packet.hh b/src/mem/packet.hh index 07c086cd5..c58862270 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. -- cgit v1.2.3 From 204d1776caa17329b84e5ebbe50fca4f1e80c100 Mon Sep 17 00:00:00 2001 From: Brad Beckmann Date: Wed, 18 Nov 2009 13:55:58 -0800 Subject: ruby: Fixed Directory memory destructor --- src/mem/ruby/system/DirectoryMemory.cc | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/mem/ruby/system/DirectoryMemory.cc b/src/mem/ruby/system/DirectoryMemory.cc index c87be94a2..e230059ad 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: 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(+) (limited to 'src') diff --git a/src/mem/rubymem.cc b/src/mem/rubymem.cc index 9a1a7927d..74a6e390e 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]); -- cgit v1.2.3 From 4d731a522dba6d4c8146bfce3633142b48ec50b6 Mon Sep 17 00:00:00 2001 From: Brad Beckmann Date: Wed, 18 Nov 2009 13:55:58 -0800 Subject: m5: fixed destructor to deschedule the tickEvent and event --- src/dev/mc146818.cc | 2 ++ 1 file changed, 2 insertions(+) (limited to 'src') diff --git a/src/dev/mc146818.cc b/src/dev/mc146818.cc index 0bb6558c8..2e6ed2a4b 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 -- cgit v1.2.3 From f54790977b319a3dafdc58c3ff4a0c28780bad4c Mon Sep 17 00:00:00 2001 From: Brad Beckmann Date: Wed, 18 Nov 2009 13:55:58 -0800 Subject: 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(-) (limited to 'src') diff --git a/src/dev/ide_ctrl.cc b/src/dev/ide_ctrl.cc index a8cceda1f..87dc0b2aa 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) -- cgit v1.2.3 From faf1d97f2447f0e3b9dce9fb06e9e87e496333a3 Mon Sep 17 00:00:00 2001 From: Brad Beckmann Date: Wed, 18 Nov 2009 13:55:58 -0800 Subject: 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(-) (limited to 'src') diff --git a/src/mem/protocol/MI_example-dir.sm b/src/mem/protocol/MI_example-dir.sm index c045419b6..0061a2838 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 e883288df..0f4894b3a 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 d4d557200..3cdb74e49 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 187dc7a68..8113087aa 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 -- cgit v1.2.3 From b5d2052fa0b7c62372e1b936f2654f700e831b68 Mon Sep 17 00:00:00 2001 From: Brad Beckmann Date: Wed, 18 Nov 2009 13:55:58 -0800 Subject: m5: Fixed bug in atomic cpu destructor --- src/cpu/simple/atomic.cc | 3 +++ 1 file changed, 3 insertions(+) (limited to 'src') diff --git a/src/cpu/simple/atomic.cc b/src/cpu/simple/atomic.cc index c092b5b1f..05b4ca3e2 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 -- cgit v1.2.3 From e84881b7a353e8a45640f7d53fa032003272656a Mon Sep 17 00:00:00 2001 From: Brad Beckmann Date: Wed, 18 Nov 2009 13:55:58 -0800 Subject: ruby: Removed unused action z_stall --- src/mem/protocol/MI_example-dma.sm | 4 ---- 1 file changed, 4 deletions(-) (limited to 'src') diff --git a/src/mem/protocol/MI_example-dma.sm b/src/mem/protocol/MI_example-dma.sm index 0f4894b3a..79c42e719 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; -- cgit v1.2.3 From cc2db929cbdb95168600de42a45a361f3a9e7318 Mon Sep 17 00:00:00 2001 From: Brad Beckmann Date: Wed, 18 Nov 2009 13:55:58 -0800 Subject: 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(+) (limited to 'src') diff --git a/src/mem/slicc/ast/TransitionDeclAST.py b/src/mem/slicc/ast/TransitionDeclAST.py index ef745fd50..a941d7b0c 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) -- cgit v1.2.3 From 994169327a232a4325d529a7071c295fa39cf7d2 Mon Sep 17 00:00:00 2001 From: Brad Beckmann Date: Wed, 18 Nov 2009 13:55:58 -0800 Subject: 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(-) (limited to 'src') diff --git a/src/mem/slicc/symbols/StateMachine.py b/src/mem/slicc/symbols/StateMachine.py index e54d6a435..8583ed46b 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) -- cgit v1.2.3 From ed54ecf1c8f66d544385bbaa0d5902d5af4394e3 Mon Sep 17 00:00:00 2001 From: Brad Beckmann Date: Wed, 18 Nov 2009 13:55:58 -0800 Subject: 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(+) (limited to 'src') diff --git a/src/mem/slicc/ast/MethodCallExprAST.py b/src/mem/slicc/ast/MethodCallExprAST.py index d423ee4a7..3f9b250c1 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 -- cgit v1.2.3 From 8b0f970084895dcef026e5720a1cd7c34afbc47a Mon Sep 17 00:00:00 2001 From: Brad Beckmann Date: Wed, 18 Nov 2009 13:55:58 -0800 Subject: 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(-) (limited to 'src') diff --git a/src/mem/ruby/buffers/MessageBuffer.cc b/src/mem/ruby/buffers/MessageBuffer.cc index 3928e94e6..eaa396547 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 3ca6790d0..dfb66dfdf 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 1a45340ed..f6a217c91 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)); } } -- cgit v1.2.3 From 7ab484624faa4445f35333241c25159b352a0921 Mon Sep 17 00:00:00 2001 From: Brad Beckmann Date: Wed, 18 Nov 2009 16:33:35 -0800 Subject: 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 (limited to 'src') diff --git a/src/mem/ruby/system/CacheMemory.cc b/src/mem/ruby/system/CacheMemory.cc new file mode 100644 index 000000000..8d5ba3270 --- /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: ruby: fix CacheMemory destructor --- src/mem/ruby/system/CacheMemory.cc | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'src') diff --git a/src/mem/ruby/system/CacheMemory.cc b/src/mem/ruby/system/CacheMemory.cc index 8d5ba3270..04adbcf69 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) -- cgit v1.2.3 From 7b8fcecf11813492d770a0d766fb9a9fb01be3e2 Mon Sep 17 00:00:00 2001 From: Brad Beckmann Date: Wed, 18 Nov 2009 16:34:31 -0800 Subject: 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(-) (limited to 'src') diff --git a/src/mem/ruby/config/MI_example-homogeneous.rb b/src/mem/ruby/config/MI_example-homogeneous.rb index b7842aaaf..1ed81ee42 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 1c261544d..f2564e1d3 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 04adbcf69..a5c881a61 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); -- cgit v1.2.3 From 2783a7b9ad90d04d74418d7463c255c29ffd8046 Mon Sep 17 00:00:00 2001 From: Brad Beckmann Date: Wed, 18 Nov 2009 16:34:31 -0800 Subject: 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. --- src/mem/protocol/RubySlicc_ComponentMapping.sm | 2 ++ .../slicc_interface/RubySlicc_ComponentMapping.cc | 38 ++++++++++++++++++++++ .../slicc_interface/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 (limited to 'src') diff --git a/src/mem/protocol/RubySlicc_ComponentMapping.sm b/src/mem/protocol/RubySlicc_ComponentMapping.sm index 559e54a8c..2a027554e 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 000000000..4d37b0007 --- /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 96405c8dd..222ff86f8 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 2b20892ba..6ba614fa9 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 a5c881a61..630b94542 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 00cd8ae35..856b7bcac 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; }; -- cgit v1.2.3 From b0973035b4db86052c1d5d67e8695bdaa27130c2 Mon Sep 17 00:00:00 2001 From: Brad Beckmann Date: Wed, 18 Nov 2009 16:34:31 -0800 Subject: 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 (limited to 'src') diff --git a/src/mem/protocol/MOESI_hammer-cache.sm b/src/mem/protocol/MOESI_hammer-cache.sm new file mode 100644 index 000000000..d244a9b93 --- /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 000000000..836fa9787 --- /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 000000000..43e00a2d1 --- /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 000000000..8ff931e04 --- /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 -- cgit v1.2.3 From 877be2009c0871effb3494b52ce5221d58a594d6 Mon Sep 17 00:00:00 2001 From: Brad Beckmann Date: Wed, 18 Nov 2009 16:34:32 -0800 Subject: 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(-) (limited to 'src') diff --git a/src/mem/protocol/MOESI_hammer-cache.sm b/src/mem/protocol/MOESI_hammer-cache.sm index d244a9b93..6fb5091af 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 836fa9787..0f7c58acd 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 43e00a2d1..b4da617cc 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 8ff931e04..d49350e32 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 ded0814d2..7be9fd97e 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', -- cgit v1.2.3 From bc12b8432d9c576d62f6bdaabb7d78c7703a2e34 Mon Sep 17 00:00:00 2001 From: Brad Beckmann Date: Wed, 18 Nov 2009 16:34:32 -0800 Subject: ruby: Hammer ruby configuration support --- src/mem/protocol/MOESI_hammer-cache.sm | 2 +- src/mem/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 (limited to 'src') diff --git a/src/mem/protocol/MOESI_hammer-cache.sm b/src/mem/protocol/MOESI_hammer-cache.sm index 6fb5091af..3b2240800 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 000000000..02af0ec27 --- /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 000000000..1e8d0d4ba --- /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 160f25411..48169a25f 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 -- cgit v1.2.3 From dbb2c111cccacad4e331bfded3b316e3c78dc63c Mon Sep 17 00:00:00 2001 From: Brad Beckmann Date: Wed, 18 Nov 2009 16:34:32 -0800 Subject: ruby: Added a memory controller feature to MOESI hammer --- src/mem/protocol/MOESI_hammer-dir.sm | 250 +++++++++++++++++++++++++++++++---- 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, 222 insertions(+), 31 deletions(-) (limited to 'src') diff --git a/src/mem/protocol/MOESI_hammer-dir.sm b/src/mem/protocol/MOESI_hammer-dir.sm index 0f7c58acd..49efaffb6 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; } + 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(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, O) { + transition(WB, Writeback_Dirty, WB_E_W) { l_writeDataToMemory; + l_queueMemoryWBRequest; j_popIncomingUnblockQueue; } - transition(WB, Writeback_Exclusive_Dirty, E) { + 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 b4da617cc..c9f146819 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 1e8d0d4ba..d3735028b 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 48169a25f..da7fa17c7 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 -- cgit v1.2.3 From cef3c5616358912b45aafac490bf182c1a8def04 Mon Sep 17 00:00:00 2001 From: Brad Beckmann Date: Wed, 18 Nov 2009 16:34:32 -0800 Subject: 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 (limited to 'src') diff --git a/src/mem/protocol/MOESI_hammer-dir.sm b/src/mem/protocol/MOESI_hammer-dir.sm index 49efaffb6..b9b001e40 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 000000000..b217923a4 --- /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 c9f146819..5d8226eb6 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 d49350e32..31ad47c2e 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 da7fa17c7..bb054ec4e 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 -- cgit v1.2.3 From 8011e80725dfd2cba0cdc19917a0f740a1b40a06 Mon Sep 17 00:00:00 2001 From: Brad Beckmann Date: Wed, 18 Nov 2009 16:34:32 -0800 Subject: 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 (limited to 'src') diff --git a/src/mem/ruby/system/PersistentTable.cc b/src/mem/ruby/system/PersistentTable.cc new file mode 100644 index 000000000..1e056f6e5 --- /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 000000000..ab000843d --- /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 -- cgit v1.2.3 From 20f872ed2a5dd7c1c08bbafc1cd5e82d6cc7444d Mon Sep 17 00:00:00 2001 From: Brad Beckmann Date: Wed, 18 Nov 2009 16:34:32 -0800 Subject: 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(-) (limited to 'src') diff --git a/src/mem/slicc/symbols/StateMachine.py b/src/mem/slicc/symbols/StateMachine.py index 8583ed46b..008438869 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(''' -- cgit v1.2.3 From c9764b1ff1cfa3d1d82026e00cc5b4279c87cad0 Mon Sep 17 00:00:00 2001 From: Brad Beckmann Date: Wed, 18 Nov 2009 16:34:32 -0800 Subject: 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(-) (limited to 'src') diff --git a/src/mem/slicc/symbols/SymbolTable.py b/src/mem/slicc/symbols/SymbolTable.py index 17d7dfad3..6b1bf13e6 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 -- cgit v1.2.3 From dcac2ec24ce6f57ae7e3061a662c1657d486f6ec Mon Sep 17 00:00:00 2001 From: Brad Beckmann Date: Wed, 18 Nov 2009 16:34:32 -0800 Subject: 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(-) (limited to 'src') diff --git a/src/mem/ruby/buffers/MessageBuffer.cc b/src/mem/ruby/buffers/MessageBuffer.cc index eaa396547..d157e2a94 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 dfb66dfdf..8440c3335 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 f6a217c91..adf7ee21e 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)); } } -- cgit v1.2.3 From 5d8a669539a142ece820cf0c82722ea1c755d7cd Mon Sep 17 00:00:00 2001 From: Brad Beckmann Date: Wed, 18 Nov 2009 16:34:33 -0800 Subject: Resurrection of the CMP token protocol to GEM5 --- src/mem/protocol/MOESI_CMP_token-L1cache.sm | 353 +++++---- 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 +++ src/mem/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, 1581 insertions(+), 339 deletions(-) create mode 100644 src/mem/protocol/MOESI_CMP_token-dma.sm create mode 100644 src/mem/ruby/config/MOESI_CMP_token.rb (limited to 'src') diff --git a/src/mem/protocol/MOESI_CMP_token-L1cache.sm b/src/mem/protocol/MOESI_CMP_token-L1cache.sm index ab58c5c00..3fb4a8862 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)); - } - } - - bool okToIssueStarving(Address addr) { - return persistentTable.okToIssueStarving(addr); +// 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, 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 0a58ed5cf..9a5c400f2 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 1592fd123..7925a8fe0 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") { - - MessageBuffer requestFromDir, network="To", virtual_network="1", ordered="false"; - MessageBuffer responseFromDir, network="To", virtual_network="2", 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"; +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 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 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"])'; + + MemoryControl memBuffer, factory='RubySystem::getMemoryControl(m_cfg["memory_controller_name"])'; - PersistentTable persistentTable, constructor_hack="i"; + 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, 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(O, Tokens) { + 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; } + transition(NO_W, Memory_Data, NO) { + d_sendMemoryDataWithAllTokens; + l_popMemQueue; + } + + // Trans. from NO_DW + transition(NO_DW, Request_Timeout) { + ut_unsetReissueTimer; + px_tryIssuingPersistentGETXRequest; + } + + transition(NO_DW, Lockdown, DW_L) { + aa_sendTokensToStarver; + l_popIncomingPersistentQueue; + } + + // 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, {GETX, GETS}) { + transition({L, DW_L, DR_L}, {GETX, GETS}) { j_popIncomingRequestQueue; } - transition(L, Lockdown) { + transition({L, DW_L, DR_L, L_W, DR_L_W}, Lockdown) { l_popIncomingPersistentQueue; } - // we could change this to write the data to memory and send it cleanly - transition(L, Data_Owner) { + // + // 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 000000000..550a36ae0 --- /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 2a75ce644..40c16b5e1 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 ae4a6d6ec..a41226f90 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 312682bd7..e1771448f 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 0c8423c85..3559f042f 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 32771235f..35bb4ec43 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 000000000..ba963dc06 --- /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 83020742e..566055f74 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 f2564e1d3..c470ca92f 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 bb054ec4e..f338f4e3f 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 1e056f6e5..58b67ea60 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 ab000843d..8cbb48817 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 496fce2fd..4ca1af114 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') -- cgit v1.2.3