summaryrefslogtreecommitdiff
path: root/src/mem/slicc/symbols
diff options
context:
space:
mode:
Diffstat (limited to 'src/mem/slicc/symbols')
-rw-r--r--src/mem/slicc/symbols/Action.hh52
-rw-r--r--src/mem/slicc/symbols/Event.hh45
-rw-r--r--src/mem/slicc/symbols/Func.cc144
-rw-r--r--src/mem/slicc/symbols/Func.hh96
-rw-r--r--src/mem/slicc/symbols/State.hh45
-rw-r--r--src/mem/slicc/symbols/StateMachine.cc993
-rw-r--r--src/mem/slicc/symbols/StateMachine.hh141
-rw-r--r--src/mem/slicc/symbols/Symbol.cc72
-rw-r--r--src/mem/slicc/symbols/Symbol.hh100
-rw-r--r--src/mem/slicc/symbols/SymbolTable.cc934
-rw-r--r--src/mem/slicc/symbols/SymbolTable.hh121
-rw-r--r--src/mem/slicc/symbols/Transition.cc173
-rw-r--r--src/mem/slicc/symbols/Transition.hh120
-rw-r--r--src/mem/slicc/symbols/Type.cc746
-rw-r--r--src/mem/slicc/symbols/Type.hh154
-rw-r--r--src/mem/slicc/symbols/Var.cc57
-rw-r--r--src/mem/slicc/symbols/Var.hh98
17 files changed, 4091 insertions, 0 deletions
diff --git a/src/mem/slicc/symbols/Action.hh b/src/mem/slicc/symbols/Action.hh
new file mode 100644
index 000000000..0f6e49290
--- /dev/null
+++ b/src/mem/slicc/symbols/Action.hh
@@ -0,0 +1,52 @@
+
+/*
+ * 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 "Symbol.hh"
+
+class Action : public Symbol {
+public:
+ Action(string id,
+ const Map<Var*, string>& resources,
+ const Location& location,
+ const Map<string, string>& pairs) : Symbol(id, location, pairs) { m_resources = resources; }
+ const Map<Var*, string>& getResources() const { return m_resources; }
+ void print(ostream& out) const { out << "[Action: " << getIdent() << "]"; }
+
+private:
+ Map<Var*, string> m_resources;
+};
+
+#endif //ACTION_H
diff --git a/src/mem/slicc/symbols/Event.hh b/src/mem/slicc/symbols/Event.hh
new file mode 100644
index 000000000..f272e8eb1
--- /dev/null
+++ b/src/mem/slicc/symbols/Event.hh
@@ -0,0 +1,45 @@
+
+/*
+ * 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 "Symbol.hh"
+
+class Event : public Symbol {
+public:
+ Event(string id, const Location& location, const Map<string, string>& pairs) : Symbol(id, location, pairs) {}
+ void print(ostream& out) const { out << "[Event: " << getIdent() << "]"; }
+};
+
+#endif //EVENT_H
diff --git a/src/mem/slicc/symbols/Func.cc b/src/mem/slicc/symbols/Func.cc
new file mode 100644
index 000000000..1af1e299c
--- /dev/null
+++ b/src/mem/slicc/symbols/Func.cc
@@ -0,0 +1,144 @@
+
+/*
+ * 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.C
+ *
+ * Description: See Func.h
+ *
+ * $Id$
+ *
+ */
+
+#include "Func.hh"
+#include "SymbolTable.hh"
+#include "fileio.hh"
+#include "StateMachine.hh"
+
+Func::Func(string id, const Location& location,
+ Type* type_ptr, const Vector<Type*>& param_type_vec,
+ const Vector<string>& param_string_vec, string body,
+ const Map<string, string>& 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; i<size; i++) {
+ // Generate code
+ if (i != 0) {
+ code += ", ";
+ }
+ code += m_param_string_vec[i];
+ }
+ code += ");\n";
+ }
+}
+
+// This write a function of object Chip
+void Func::writeCFiles(string path) const
+{
+ if (isExternal()) {
+ // Do nothing
+ } else {
+ ostringstream out;
+
+ // Header
+ out << "/** Auto generated C++ code started by "<<__FILE__<<":"<<__LINE__<< " */" << endl;
+ out << endl;
+ out << "#include \"Types.hh\"" << endl;
+ out << "#include \"Chip.hh\"" << endl;
+ if (m_isInternalMachineFunc) {
+ out << "#include \"" << m_machineStr << "_Controller.hh\"" << endl;
+ }
+ out << endl;
+
+ // Generate function header
+ string code;
+ Type* void_type_ptr = g_sym_table.getType("void");
+ string return_type = m_type_ptr->cIdent();
+ 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<size; i++) {
+ // Generate code
+ if (i != 0) {
+ code += ", ";
+ }
+ code += m_param_string_vec[i];
+ }
+ code += ")";
+
+ // Function body
+ code += "\n{\n";
+ code += m_body;
+ code += "}\n";
+ out << code << endl;
+
+ // Write it out
+ conditionally_write_file(path + cIdent() + ".cc", out);
+ }
+}
+
+void Func::print(ostream& out) const
+{
+}
diff --git a/src/mem/slicc/symbols/Func.hh b/src/mem/slicc/symbols/Func.hh
new file mode 100644
index 000000000..763827701
--- /dev/null
+++ b/src/mem/slicc/symbols/Func.hh
@@ -0,0 +1,96 @@
+
+/*
+ * 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.h
+ *
+ * Description:
+ *
+ * $Id$
+ *
+ */
+
+#ifndef FUNC_H
+#define FUNC_H
+
+#include "slicc_global.hh"
+#include "Type.hh"
+class StateMachine;
+
+class Func : public Symbol {
+public:
+ // Constructors
+ Func(string id, const Location& location,
+ Type* type_ptr, const Vector<Type*>& param_type_vec, const Vector<string>& param_string_vec,
+ string body, const Map<string, string>& pairs, StateMachine* machine_ptr);
+
+ // Destructor
+ ~Func() {}
+
+ // Public Methods
+ string cIdent() const { return m_c_ident; }
+ const Vector<Type*>& getParamTypes() const { return m_param_type_vec; }
+ Type* getReturnType() const { return m_type_ptr; }
+ void writeCFiles(string path) const;
+ 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<Type*> m_param_type_vec;
+ Vector<string> 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/State.hh b/src/mem/slicc/symbols/State.hh
new file mode 100644
index 000000000..cac743e57
--- /dev/null
+++ b/src/mem/slicc/symbols/State.hh
@@ -0,0 +1,45 @@
+
+/*
+ * 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 "Symbol.hh"
+
+class State : public Symbol {
+public:
+ State(string id, const Location& location, const Map<string, string>& pairs) : Symbol(id, location, pairs) {}
+ void print(ostream& out) const { out << "[State: " << getIdent() << "]"; }
+};
+
+#endif //STATE_H
diff --git a/src/mem/slicc/symbols/StateMachine.cc b/src/mem/slicc/symbols/StateMachine.cc
new file mode 100644
index 000000000..d4436870e
--- /dev/null
+++ b/src/mem/slicc/symbols/StateMachine.cc
@@ -0,0 +1,993 @@
+
+/*
+ * 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 "StateMachine.hh"
+#include "fileio.hh"
+#include "html_gen.hh"
+#include "Action.hh"
+#include "Event.hh"
+#include "State.hh"
+#include "Transition.hh"
+#include "Var.hh"
+#include "SymbolTable.hh"
+#include "util.hh"
+#include "Vector.hh"
+
+StateMachine::StateMachine(string ident, const Location& location, const Map<string, string>& pairs)
+ : Symbol(ident, location, pairs)
+{
+ m_table_built = false;
+}
+
+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; i<size; i++) {
+ if (m_actions[i]->getIdent() == 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<Transition*>());
+ for(eventIndex=0; eventIndex < numEvents; eventIndex++) {
+ m_table[stateIndex].insertAtBottom(NULL);
+ }
+ }
+
+ for(int i=0; i<numTransitions; i++) {
+ Transition* trans_ptr = m_transitions[i];
+
+ // 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.
+
+ Vector<Action*> 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) const
+{
+ string comp = getIdent();
+ string filename;
+
+ // 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 method declarations for the class declaration
+ {
+ ostringstream sstr;
+ printControllerH(sstr, comp);
+ conditionally_write_file(path + comp + "_Controller.hh", 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; i<m_internal_func_vec.size(); i++) {
+ m_internal_func_vec[i]->writeCFiles(path);
+ }
+
+}
+
+void StateMachine::printControllerH(ostream& out, string component) const
+{
+ 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 \"Global.hh\"" << endl;
+ out << "#include \"Consumer.hh\"" << endl;
+ out << "#include \"TransitionResult.hh\"" << endl;
+ out << "#include \"Types.hh\"" << endl;
+ out << "#include \"" << component << "_Profiler.hh\"" << endl;
+ out << endl;
+
+ // for adding information to the protocol debug trace
+ out << "extern stringstream " << component << "_" << "transitionComment;" << endl;
+
+ out << "class " << component << "_Controller : public Consumer {" << 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 << " friend class Chip;" << endl;
+ out << "#endif /* CHECK_COHERENCE */" << endl;
+
+ out << "public:" << endl;
+ out << " " << component << "_Controller(Chip* chip_ptr, int version);" << endl;
+ out << " void print(ostream& out) const;" << endl;
+ out << " void wakeup();" << endl;
+ out << " static void dumpStats(ostream& out) { s_profiler.dumpStats(out); }" << endl;
+ out << " static void clearStats() { s_profiler.clearStats(); }" << endl;
+ out << "private:" << 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 << " Chip* m_chip_ptr;" << endl;
+ out << " NodeID m_id;" << endl;
+ out << " NodeID m_version;" << endl;
+ out << " MachineID m_machineID;" << endl;
+ out << " static " << component << "_Profiler s_profiler;" << endl;
+
+ // internal function protypes
+ out << " // Internal functions" << endl;
+ for(int i=0; i<m_internal_func_vec.size(); i++) {
+ Func* func = m_internal_func_vec[i];
+ string proto;
+ func->funcPrototype(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;
+ }
+ out << "};" << endl;
+ out << "#endif // " << component << "_CONTROLLER_H" << endl;
+}
+
+void StateMachine::printControllerC(ostream& out, string component) const
+{
+ 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 \"Global.hh\"" << endl;
+ out << "#include \"RubySlicc_includes.hh\"" << endl;
+ out << "#include \"" << component << "_Controller.hh\"" << endl;
+ out << "#include \"" << component << "_State.hh\"" << endl;
+ out << "#include \"" << component << "_Event.hh\"" << endl;
+ out << "#include \"Types.hh\"" << endl;
+ out << "#include \"System.hh\"" << endl;
+ out << "#include \"Chip.hh\"" << endl;
+ out << 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 static profiler defn */" << endl;
+ out << component << "_Profiler " << component << "_Controller::s_profiler;" << endl;
+ out << endl;
+
+ out << "/** \\brief constructor */" << endl;
+ out << component << "_Controller::" << component
+ << "_Controller(Chip* chip_ptr, int version)" << endl;
+ out << "{" << endl;
+ out << " m_chip_ptr = chip_ptr;" << endl;
+ out << " m_id = m_chip_ptr->getID();" << endl;
+ out << " m_version = version;" << endl;
+ out << " m_machineID.type = MachineType_" << component << ";" << endl;
+ out << " m_machineID.num = m_id*RubyConfig::numberOf"<< component << "PerChip()+m_version;" << endl;
+
+ // Set the queue consumers
+ for(int i=0; i < m_in_ports.size(); i++) {
+ const Var* port = m_in_ports[i];
+ out << " " << port->getCode() << ".setConsumer(this);" << endl;
+ }
+
+ out << endl;
+ // Set the queue descriptions
+ for(int i=0; i < m_in_ports.size(); i++) {
+ const Var* port = m_in_ports[i];
+ out << " " << port->getCode()
+ << ".setDescription(\"[Chip \" + int_to_string(m_chip_ptr->getID()) + \" \" + int_to_string(m_version) + \", "
+ << component << ", " << port->toString() << "]\");" << endl;
+ }
+
+ // Initialize the transition profiling
+ out << endl;
+ for(int i=0; i<numTransitions(); i++) {
+ const Transition& t = getTransition(i);
+ const Vector<Action*>& action_vec = t.getActions();
+ int numActions = action_vec.size();
+
+ // Figure out if we stall
+ bool stall = false;
+ for (int i=0; i<numActions; i++) {
+ if(action_vec[i]->getIdent() == "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;
+ }
+ }
+
+ out << "}" << endl;
+
+ out << endl;
+
+ out << "void " << component << "_Controller::print(ostream& out) const { out << \"[" << component
+ << "_Controller \" << m_chip_ptr->getID() << \" \" << m_version << \"]\"; }" << 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;
+ out << action.lookupPair("c_code");
+ out << "}" << endl;
+ }
+ out << endl;
+ }
+}
+
+void StateMachine::printCWakeup(ostream& out, string component) const
+{
+ out << "// Auto generated C++ code started by "<<__FILE__<<":"<<__LINE__<< endl;
+ out << "// " << getIdent() << ": " << getShorthand() << endl;
+ out << endl;
+ out << "#include \"Global.hh\"" << endl;
+ out << "#include \"RubySlicc_includes.hh\"" << endl;
+ out << "#include \"" << component << "_Controller.hh\"" << endl;
+ out << "#include \"" << component << "_State.hh\"" << endl;
+ out << "#include \"" << component << "_Event.hh\"" << endl;
+ out << "#include \"Types.hh\"" << endl;
+ out << "#include \"System.hh\"" << endl;
+ out << "#include \"Chip.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 <= RubyConfig::" << getIdent() << "TransitionsPerCycle());" << endl;
+ out << " if (counter == RubyConfig::" << getIdent() << "TransitionsPerCycle()) {" << 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
+ for(int i=0; i < m_in_ports.size(); i++) {
+ const Var* port = m_in_ports[i];
+ assert(port->existPair("c_code_in_port"));
+ out << " // "
+ << component << "InPort " << port->toString()
+ << endl;
+ out << port->lookupPair("c_code_in_port");
+ 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;
+}
+
+void StateMachine::printCSwitch(ostream& out, string component) const
+{
+ out << "// Auto generated C++ code started by "<<__FILE__<<":"<<__LINE__<< endl;
+ out << "// " << getIdent() << ": " << getShorthand() << endl;
+ out << endl;
+ out << "#include \"Global.hh\"" << endl;
+ out << "#include \"" << component << "_Controller.hh\"" << endl;
+ out << "#include \"" << component << "_State.hh\"" << endl;
+ out << "#include \"" << component << "_Event.hh\"" << endl;
+ out << "#include \"Types.hh\"" << endl;
+ out << "#include \"System.hh\"" << endl;
+ out << "#include \"Chip.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 (PROTOCOL_DEBUG_TRACE) {" << endl
+ << " g_system_ptr->getProfiler()->profileTransition(\"" << component
+ << "\", m_chip_ptr->getID(), 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 (PROTOCOL_DEBUG_TRACE) {" << endl
+ << " g_system_ptr->getProfiler()->profileTransition(\"" << component
+ << "\", m_chip_ptr->getID(), 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 (PROTOCOL_DEBUG_TRACE) {" << endl
+ << " g_system_ptr->getProfiler()->profileTransition(\"" << component
+ << "\", m_chip_ptr->getID(), 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<string, Vector<string> > code_map; // This map will allow suppress generating duplicate code
+ Vector<string> code_vec;
+
+ for(int i=0; i<numTransitions(); i++) {
+ const Transition& t = getTransition(i);
+ string case_string = component + "_State_" + t.getStatePtr()->getIdent()
+ + ", " + 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*>& action_vec = t.getActions();
+ int numActions = action_vec.size();
+
+ // Check for resources
+ Vector<string> code_sorter;
+ const Map<Var*, string>& res = t.getResources();
+ Vector<Var*> res_keys = res.keys();
+ for (int i=0; i<res_keys.size(); i++) {
+ string temp_code;
+ if (res_keys[i]->getType()->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; i<code_sorter.size(); i++) {
+ code += code_sorter[i];
+ }
+
+ // Figure out if we stall
+ bool stall = false;
+ for (int i=0; i<numActions; i++) {
+ if(action_vec[i]->getIdent() == "z_stall") {
+ stall = true;
+ }
+ }
+
+ if (stall) {
+ code += " return TransitionResult_ProtocolStall;\n";
+ } else {
+ for (int i=0; i<numActions; i++) {
+ code += " " + action_vec[i]->getIdent() + "(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<string> 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; i<code_vec.size(); i++) {
+ string code = code_vec[i];
+
+ // Iterative over all the multiple transitions that share the same code
+ for (int case_num=0; case_num<code_map.lookup(code).size(); case_num++) {
+ string case_string = code_map.lookup(code)[case_num];
+ out << " case HASH_FUN(" << case_string << "):" << endl;
+ }
+ out << code;
+ }
+
+ out << " default:" << endl;
+ out << " WARN_EXPR(m_id);" << endl;
+ out << " WARN_EXPR(m_version);" << endl;
+ out << " WARN_EXPR(g_eventQueue_ptr->getTime());" << 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) const
+{
+ 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 \"Global.hh\"" << endl;
+ out << "#include \"" << component << "_State.hh\"" << endl;
+ out << "#include \"" << component << "_Event.hh\"" << endl;
+ out << endl;
+ out << "class " << component << "_Profiler {" << endl;
+ out << "public:" << endl;
+ out << " " << component << "_Profiler();" << 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 << "};" << endl;
+ out << "#endif // " << component << "_PROFILER_H" << endl;
+}
+
+void StateMachine::printProfilerC(ostream& out, string component) const
+{
+ out << "// Auto generated C++ code started by "<<__FILE__<<":"<<__LINE__<< endl;
+ out << "// " << getIdent() << ": " << getShorthand() << endl;
+ out << endl;
+ out << "#include \"" << 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;
+
+ // 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 << " ---\" << 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 += "<A href=\"" + click_href + "\" ";
+ temp += "target=\"" + click_target + "\" ";
+ string javascript = "if (parent.frames[" + over_target_num + "].location != parent.location + '" + over_href + "') { parent.frames[" + over_target_num + "].location='" + over_href + "' }";
+ // string javascript = "parent." + target + ".location='" + href + "'";
+ temp += "onMouseOver=\"" + javascript + "\" ";
+ temp += ">" + text + "</A>";
+ 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) const
+{
+ string filename;
+ string component = getIdent();
+
+ /*
+ {
+ ostringstream out;
+ out << "<html>" << endl;
+ out << "<head>" << endl;
+ out << "<title>" << component << "</title>" << endl;
+ out << "</head>" << endl;
+ out << "<frameset rows=\"30,30,*\" frameborder=\"1\">" << endl;
+ out << " <frame name=\"Status\" src=\"empty.html\" marginheight=\"1\">" << endl;
+ out << " <frame name=\"Table\" src=\"" << component << "_table.html\" marginheight=\"1\">" << endl;
+ out << "</frameset>" << endl;
+ out << "</html>" << 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<numStates(); i++) {
+ ostringstream out;
+ printHTMLTransitions(out, i);
+
+ // -- Write file
+ filename = component + "_table_" + getState(i).getIdent() + ".html";
+ conditionally_write_file(path + filename, out);
+ }
+
+ // Generate action descriptions
+ for(int i=0; i<numActions(); i++) {
+ ostringstream out;
+ createHTMLSymbol(getAction(i), "Action", out);
+
+ // -- Write file
+ filename = component + "_action_" + getAction(i).getIdent() + ".html";
+ conditionally_write_file(path + filename, out);
+ }
+
+ // Generate state descriptions
+ for(int i=0; i<numStates(); i++) {
+ ostringstream out;
+ createHTMLSymbol(getState(i), "State", out);
+
+ // -- Write file
+ filename = component + "_State_" + getState(i).getIdent() + ".html";
+ conditionally_write_file(path + filename, out);
+ }
+
+ // Generate event descriptions
+ for(int i=0; i<numEvents(); i++) {
+ ostringstream out;
+ createHTMLSymbol(getEvent(i), "Event", out);
+
+ // -- Write file
+ filename = component + "_Event_" + getEvent(i).getIdent() + ".html";
+ conditionally_write_file(path + filename, out);
+ }
+}
+
+void StateMachine::printHTMLTransitions(ostream& out, int active_state) const
+{
+ // -- Prolog
+ out << "<HTML><BODY link=\"blue\" vlink=\"blue\">" << endl;
+
+ // -- Header
+ out << "<H1 align=\"center\">" << formatHTMLShorthand(getShorthand()) << ": " << endl;
+ Vector<StateMachine*> machine_vec = g_sym_table.getStateMachines();
+ for (int i=0; i<machine_vec.size(); i++) {
+ StateMachine* type = machine_vec[i];
+ if (i != 0) {
+ out << " - ";
+ }
+ if (type == this) {
+ out << type->getIdent() << endl;
+ } else {
+ out << "<A target=\"Table\"href=\"" + type->getIdent() + "_table.html\">" + type->getIdent() + "</A> " << endl;
+ }
+ }
+ out << "</H1>" << endl;
+
+ // -- Table header
+ out << "<TABLE border=1>" << endl;
+
+ // -- Column headers
+ out << "<TR>" << endl;
+
+ // -- First column header
+ out << " <TH> </TH>" << endl;
+
+ for(int event = 0; event < numEvents(); event++ ) {
+ out << " <TH bgcolor=white>";
+ out << frameRef(getIdent() + "_Event_" + getEvent(event).getIdent() + ".html", "Status", "1", formatHTMLShorthand(getEvent(event).getShorthand()));
+ out << "</TH>" << endl;
+ }
+
+ out << "</TR>" << endl;
+
+ // -- Body of table
+ for(int state = 0; state < numStates(); state++ ) {
+ out << "<TR>" << endl;
+
+ // -- Each row
+ if (state == active_state) {
+ out << " <TH bgcolor=yellow>";
+ } else {
+ out << " <TH bgcolor=white>";
+ }
+
+ 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 << "</TH>" << 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<Action*> 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 << " <TD bgcolor=#C0C000>";
+ } else {
+ out << " <TD bgcolor=lightgrey>";
+ }
+ } else if (active_state < numStates() && (trans_ptr->getNextStatePtr()->getIdent() == getState(active_state).getIdent())) {
+ out << " <TD bgcolor=aqua>";
+ } else if (state == active_state) {
+ out << " <TD bgcolor=yellow>";
+ } else {
+ out << " <TD bgcolor=white>";
+ }
+
+ out << actions_str;
+ if ((nextState.length() != 0) && (actions_str.length() != 0)) {
+ out << "/";
+ }
+ out << nextState;
+ out << "</TD>" << endl;
+ } else {
+ // This is the no transition case
+ if (state == active_state) {
+ out << " <TD bgcolor=#C0C000>&nbsp;</TD>" << endl;
+ } else {
+ out << " <TD bgcolor=lightgrey>&nbsp;</TD>" << endl;
+ }
+ }
+ }
+ // -- Each row
+ if (state == active_state) {
+ out << " <TH bgcolor=yellow>";
+ } else {
+ out << " <TH bgcolor=white>";
+ }
+
+ 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 << "</TH>" << endl;
+
+ out << "</TR>" << endl;
+ }
+
+ // -- Column footer
+ out << "<TR>" << endl;
+ out << " <TH> </TH>" << endl;
+
+ for(int i = 0; i < numEvents(); i++ ) {
+ out << " <TH bgcolor=white>";
+ out << frameRef(getIdent() + "_Event_" + getEvent(i).getIdent() + ".html", "Status", "1", formatHTMLShorthand(getEvent(i).getShorthand()));
+ out << "</TH>" << endl;
+ }
+ out << "</TR>" << endl;
+
+ // -- Epilog
+ out << "</TABLE>" << endl;
+ out << "</BODY></HTML>" << endl;
+}
+
+
diff --git a/src/mem/slicc/symbols/StateMachine.hh b/src/mem/slicc/symbols/StateMachine.hh
new file mode 100644
index 000000000..9f3663ed4
--- /dev/null
+++ b/src/mem/slicc/symbols/StateMachine.hh
@@ -0,0 +1,141 @@
+
+/*
+ * 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 "slicc_global.hh"
+#include "Vector.hh"
+#include "Map.hh"
+#include "Symbol.hh"
+
+class Transition;
+class Event;
+class State;
+class Action;
+class Var;
+class Func;
+
+class StateMachine : public Symbol {
+public:
+ // Constructors
+ StateMachine(string ident, const Location& location, const Map<string, string>& pairs);
+
+ // Destructor
+ ~StateMachine();
+
+ // Public Methods
+
+ // Add items to the state machine
+ // void setMachine(string ident, const Map<string, string>& 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);
+
+ // 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;
+
+ // 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(); }
+
+ void buildTable(); // Needs to be called before accessing the table
+
+ // Code generator methods
+ void writeCFiles(string path) const;
+ void writeHTMLFiles(string path) const;
+
+ void print(ostream& out) const { out << "[StateMachine: " << toString() << "]" << endl; }
+private:
+ // 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) const;
+ void printControllerC(ostream& out, string component) const;
+ void printCWakeup(ostream& out, string component) const;
+ void printCSwitch(ostream& out, string component) const;
+ void printProfilerH(ostream& out, string component) const;
+ void printProfilerC(ostream& out, string component) const;
+
+ void printHTMLTransitions(ostream& out, int active_state) const;
+
+ // Data Members (m_ prefix)
+ Vector<State*> m_states;
+ Vector<Event*> m_events;
+ Vector<Action*> m_actions;
+ Vector<Transition*> m_transitions;
+ Vector<Func*> m_internal_func_vec;
+
+ Map<State*, int> m_state_map;
+ Map<Event*, int> m_event_map;
+
+ Vector<Var*> m_in_ports;
+
+ // Table variables
+ bool m_table_built;
+ Vector<Vector<Transition*> > m_table;
+
+};
+
+// 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/Symbol.cc b/src/mem/slicc/symbols/Symbol.cc
new file mode 100644
index 000000000..3365c94eb
--- /dev/null
+++ b/src/mem/slicc/symbols/Symbol.cc
@@ -0,0 +1,72 @@
+
+/*
+ * 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 "Symbol.hh"
+
+Symbol::Symbol(string id, const Location& location, const Map<string, string>& 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
new file mode 100644
index 000000000..bca7d32db
--- /dev/null
+++ b/src/mem/slicc/symbols/Symbol.hh
@@ -0,0 +1,100 @@
+
+/*
+ * 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 "slicc_global.hh"
+#include "Map.hh"
+#include "Location.hh"
+
+class Symbol {
+public:
+ // Constructors
+ Symbol(string id, const Location& location, const Map<string, string>& 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) const {}
+ virtual void writeHTMLFiles(string path) const {}
+ 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<string, string> 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/SymbolTable.cc b/src/mem/slicc/symbols/SymbolTable.cc
new file mode 100644
index 000000000..37e233e88
--- /dev/null
+++ b/src/mem/slicc/symbols/SymbolTable.cc
@@ -0,0 +1,934 @@
+
+/*
+ * 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 "SymbolTable.hh"
+#include "fileio.hh"
+#include "html_gen.hh"
+#include "mif_gen.hh"
+#include "Action.hh"
+
+SymbolTable g_sym_table;
+
+SymbolTable::SymbolTable()
+{
+ m_sym_map_vec.setSize(1);
+ m_depth = 0;
+
+ {
+ Map<string, string> pairs;
+ pairs.add("enumeration", "yes");
+ newSym(new Type("MachineType", Location(), pairs));
+ }
+
+ {
+ Map<string, string> 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; i<size; i++) {
+ delete m_sym_vec[i];
+ }
+}
+
+void SymbolTable::newSym(Symbol* sym_ptr)
+{
+ registerSym(sym_ptr->toString(), 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<Var*>(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<string, Symbol*> m;
+ m_machine_component_map_vec.add(sym_ptr->toString(),m);
+
+}
+
+Type* SymbolTable::getType(string ident) const
+{
+ return dynamic_cast<Type*>(getSym(ident));
+}
+
+Var* SymbolTable::getVar(string ident) const
+{
+ return dynamic_cast<Var*>(getSym(ident));
+}
+
+Func* SymbolTable::getFunc(string ident) const
+{
+ return dynamic_cast<Func*>(getSym(ident));
+}
+
+StateMachine* SymbolTable::getStateMachine(string ident) const
+{
+ return dynamic_cast<StateMachine*>(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 \"RubySlicc_includes.hh\"" << endl;
+ for(int i=0; i<size; i++) {
+ Type* type = dynamic_cast<Type*>(m_sym_vec[i]);
+ if (type != NULL && !type->isPrimitive()) {
+ sstr << "#include \"" << type->cIdent() << ".hh" << "\"" << endl;
+ }
+ }
+ conditionally_write_file(path + "/Types.hh", sstr);
+ }
+
+ // Write all the symbols
+ for(int i=0; i<size; i++) {
+ m_sym_vec[i]->writeCFiles(path + '/');
+ }
+
+ writeChipFiles(path);
+}
+
+void SymbolTable::writeChipFiles(string path) const
+{
+ // Create Chip.cc and Chip.hh
+
+ // FIXME - Note: this method is _really_ ugly. Most of this
+ // functionality should be pushed into each type of symbol and use
+ // virtual methods to get the right behavior for each type of
+ // symbol. This is also more flexible, and much cleaner.
+
+ int size = m_sym_vec.size();
+
+ // Create Chip.h
+ {
+ ostringstream sstr;
+ sstr << "/** \\file Chip.h " << endl;
+ sstr << " * Auto generated C++ code started by "<<__FILE__<<":"<<__LINE__<<endl;
+ sstr << " */ " <<endl<<endl;
+
+ sstr << "#ifndef CHIP_H" << endl;
+ sstr << "#define CHIP_H" << endl;
+ sstr << endl;
+
+ // Includes
+ sstr << "#include \"Global.hh\"" << endl;
+ sstr << "#include \"Types.hh\"" << endl;
+ sstr << "#include \"AbstractChip.hh\"" << endl;
+ sstr << "class Network;" << endl;
+ sstr << endl;
+
+ // Class declarations for all Machines/Controllers
+ for(int i=0; i<size; i++) {
+ StateMachine* machine = dynamic_cast<StateMachine*>(m_sym_vec[i]);
+ if (machine != NULL) {
+ sstr << "class " << machine->getIdent() << "_Controller;" << endl;
+ }
+ }
+
+ sstr << "class Chip : public AbstractChip {" << endl;
+ sstr << "public:" << endl;
+ sstr << endl;
+ sstr << " // Constructors" << endl;
+ sstr << " Chip(NodeID chip_number, Network* net_ptr);" << endl;
+ sstr << endl;
+ sstr << " // Destructor" << endl;
+ sstr << " ~Chip();" << endl;
+ sstr << endl;
+ sstr << " // Public Methods" << endl;
+ sstr << " void recordCacheContents(CacheRecorder& tr) const;" << endl;
+ sstr << " void dumpCaches(ostream& out) const;" << endl;
+ sstr << " void dumpCacheData(ostream& out) const;" << endl;
+ sstr << " static void printStats(ostream& out);" << endl;
+ sstr << " static void clearStats();" << endl;
+ sstr << " void printConfig(ostream& out);" << endl;
+ sstr << " void print(ostream& out) const;" << endl;
+
+ // Used by coherence checker
+ sstr << "#ifdef CHECK_COHERENCE" << endl;
+ sstr << " bool isBlockShared(const Address& addr) const;" << endl;
+ sstr << " bool isBlockExclusive(const Address& addr) const;" << endl;
+ sstr << "#endif /* CHECK_COHERENCE */" << endl;
+
+ sstr << endl;
+ sstr << "private:" << endl;
+ sstr << " // Private copy constructor and assignment operator" << endl;
+ sstr << " Chip(const Chip& obj);" << endl;
+ sstr << " Chip& operator=(const Chip& obj);" << endl;
+ sstr << endl;
+ sstr << "public: // FIXME - these should not be public" << endl;
+ sstr << " // Data Members (m_ prefix)" << endl;
+ sstr << endl;
+ sstr << " Chip* m_chip_ptr;" << endl;
+ sstr << endl;
+ sstr << " // SLICC object variables" << endl;
+ sstr << endl;
+
+ // Look at all 'Vars'
+ for(int i=0; i<size; i++) {
+ Var* var = dynamic_cast<Var*>(m_sym_vec[i]);
+ if (var != NULL) {
+ if (var->existPair("chip_object")) {
+ if (var->existPair("no_chip_object")) {
+ // Do nothing
+ } else {
+ string template_hack = "";
+ if (var->existPair("template_hack")) {
+ template_hack = var->lookupPair("template_hack");
+ }
+ if (// var->existPair("network") || var->getType()->existPair("cache") ||
+// var->getType()->existPair("tbe") || var->getType()->existPair("newtbe") ||
+// var->getType()->existPair("dir") || var->getType()->existPair("persistent") ||
+// var->getType()->existPair("filter") || var->getType()->existPair("timer") ||
+// var->existPair("trigger_queue")
+ var->existPair("no_vector")
+ ) {
+ sstr << " " << var->getType()->cIdent() << template_hack << "* m_"
+ << var->cIdent() << "_ptr;" << endl;
+ } else {
+ // create pointer except those created in AbstractChip
+ if (!(var->existPair("abstract_chip_ptr"))) {
+ sstr << " Vector < " << var->getType()->cIdent() << template_hack
+ << "* > m_" << var->cIdent() << "_vec;" << endl;
+ }
+ }
+ }
+ }
+ }
+ }
+
+ sstr << endl;
+ sstr << " // SLICC machine/controller variables" << endl;
+
+ // Look at all 'Machines'
+ for(int i=0; i<size; i++) {
+ StateMachine* machine = dynamic_cast<StateMachine*>(m_sym_vec[i]);
+ if (machine != NULL) {
+ string ident = machine->getIdent() + "_Controller";
+ sstr << " Vector < " << ident << "* > m_" << ident << "_vec;\n";
+ }
+ }
+
+ sstr << endl;
+
+ sstr << " // machine external SLICC function decls\n";
+
+ // Look at all 'Functions'
+ for(int i=0; i<size; i++) {
+ Func* func = dynamic_cast<Func*>(m_sym_vec[i]);
+ if (func != NULL) {
+ string proto;
+ func->funcPrototype(proto);
+ if (proto != "") {
+ sstr << " " << proto;
+ }
+ }
+ }
+
+ sstr << "};" << endl;
+ sstr << endl;
+ sstr << "#endif // CHIP_H" << endl;
+
+ conditionally_write_file(path + "/Chip.hh", sstr);
+ }
+ // Create Chip.cc
+ {
+ ostringstream sstr;
+ sstr << "// Auto generated C++ code started by "<<__FILE__<<":"<<__LINE__<<endl<<endl;
+ sstr << "#include \"Chip.hh\"" << endl;
+ sstr << "#include \"Network.hh\"" << endl;
+ sstr << "#include \"CacheRecorder.hh\"" << endl;
+ sstr << "" << endl;
+
+ sstr << "// Includes for controllers" << endl;
+ for(int i=0; i<size; i++) {
+ StateMachine* machine = dynamic_cast<StateMachine*>(m_sym_vec[i]);
+ if (machine != NULL) {
+ sstr << "#include \"" << machine->getIdent() << "_Controller.hh\"" << endl;
+ }
+ }
+
+ sstr << "" << endl;
+ sstr << "Chip::Chip(NodeID id, Network* net_ptr):AbstractChip(id, net_ptr)" << endl;
+ sstr << "{" << endl;
+ sstr << " m_chip_ptr = this;" << endl;
+
+ // FIXME - WHY IS THIS LOOP HERE?
+ // WE SEEM TO BE CREATING A SEQUENCER HERE THEN OVERWRITTING THAT INSTANITATION
+ // IN THE NEXT LOOP
+// // find sequencer's type
+// for(int i=0; i<size; i++) {
+// Var* var = dynamic_cast<Var*>(m_sym_vec[i]);
+// if(var && var->cIdent() == "sequencer")
+// sstr << " m_sequencer_ptr = new " << var->getType()->cIdent() << "(this);\n";
+// }
+
+ // Look at all 'Vars'
+ for(int i=0; i<size; i++) {
+ Var* var = dynamic_cast<Var*>(m_sym_vec[i]);
+ if (var != NULL && var->existPair("chip_object") && !var->existPair("no_chip_object")) {
+
+ sstr << " // " << var->cIdent() << endl;
+ if (!var->existPair("network")) {
+ // Not a network port object
+ if (var->getType()->existPair("primitive")) {
+ // Normal non-object
+ // sstr << " m_" << var->cIdent() << "_ptr = new " << var->getType()->cIdent() << ";\n";
+
+ sstr << " m_" << var->cIdent();
+ sstr << "_vec.setSize(RubyConfig::numberOf";
+ sstr << var->getMachine()->getIdent() << "PerChip(m_id));" << endl;
+ sstr << " for (int i = 0; i < RubyConfig::numberOf" << var->getMachine()->getIdent()
+ << "PerChip(m_id); i++) {" << endl;
+ sstr << " m_" << var->cIdent() << "_vec[i] = new " << var->getType()->cIdent() << ";\n";
+ if (var->existPair("default")) {
+ sstr << " *(m_" << var->cIdent() << "_vec[i]) = " << var->lookupPair("default") << ";\n";
+ }
+ sstr << " }\n";
+
+ } else {
+
+ // Normal Object
+ string template_hack = "";
+ if (var->existPair("template_hack")) {
+ template_hack = var->lookupPair("template_hack");
+ }
+ if (// var->getType()->existPair("cache") || var->getType()->existPair("tbe") ||
+// var->getType()->existPair("newtbe") || var->getType()->existPair("timer") ||
+// var->getType()->existPair("dir") || var->getType()->existPair("persistent") ||
+// var->getType()->existPair("filter") || var->existPair("trigger_queue")
+ var->existPair("no_vector")) {
+ sstr << " m_" << var->cIdent() << "_ptr = new " << var->getType()->cIdent() << template_hack;
+ if (!var->getType()->existPair("non_obj") && (!var->getType()->isEnumeration())) {
+ if (var->existPair("constructor_hack")) {
+ string constructor_hack = var->lookupPair("constructor_hack");
+ sstr << "(this, " << constructor_hack << ")";
+ } else {
+ sstr << "(this)";
+ }
+ }
+ sstr << ";\n";
+ sstr << " assert(m_" << var->cIdent() << "_ptr != NULL);" << endl;
+
+ if (var->existPair("default")) {
+ sstr << " (*m_" << var->cIdent() << "_ptr) = " << var->lookupPair("default")
+ << "; // Object default" << endl;
+ } else if (var->getType()->hasDefault()) {
+ sstr << " (*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");
+ sstr << " m_" << var->cIdent() << "_ptr->setOrdering(" << ordered << ");\n";
+ }
+
+ // Set randomization
+ if (var->existPair("random")) {
+ // A buffer
+ string value = var->lookupPair("random");
+ sstr << " 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");
+ sstr << " m_" << var->cIdent() << "_ptr->setPriority(" << rank << ");\n";
+ }
+ } else if ((var->getType()->existPair("mover")) && (var->getMachine()->getIdent() == "L2Cache")) {
+ // FIXME - dnuca mover is a special case
+ sstr << " m_" << var->cIdent() << "_ptr = NULL;" << endl;
+ sstr << " if (RubyConfig::isL2CacheDNUCAMoverChip(m_id)) {" << endl;
+ sstr << " m_" << var->cIdent() << "_ptr = new " << var->getType()->cIdent() << template_hack;
+ if (!var->getType()->existPair("non_obj") && (!var->getType()->isEnumeration())) {
+ if (var->existPair("constructor_hack")) {
+ string constructor_hack = var->lookupPair("constructor_hack");
+ sstr << "(this, " << constructor_hack << ")";
+ } else {
+ sstr << "(this)";
+ }
+ }
+ sstr << ";\n";
+ sstr << " }\n";
+ } else if (var->getType()->existPair("mover") && ((var->getMachine()->getIdent() == "L1Cache") || (var->getMachine()->getIdent() == "Collector"))) {
+ sstr << " m_" << var->cIdent() << "_ptr = NULL;" << endl;
+ sstr << " \n";
+ } else {
+ sstr << " m_" << var->cIdent();
+ sstr << "_vec.setSize(RubyConfig::numberOf";
+ sstr << var->getMachine()->getIdent() << "PerChip(m_id));" << endl;
+ sstr << " for (int i = 0; i < RubyConfig::numberOf" << var->getMachine()->getIdent()
+ << "PerChip(m_id); i++) {" << endl;
+
+
+ ostringstream tail;
+ tail << template_hack;
+ if (!var->getType()->existPair("non_obj") && (!var->getType()->isEnumeration())) {
+ if (var->existPair("constructor_hack")) {
+ string constructor_hack = var->lookupPair("constructor_hack");
+ tail << "(this, " << constructor_hack << ")";
+ } else {
+ tail << "(this)";
+ }
+ }
+ tail << ";\n";
+
+
+ if(var->existPair("child_selector")){
+ string child_selector = var->lookupPair("child_selector");
+ string child_types = var->lookupPair("child_types");
+ string::iterator it = child_types.begin();
+
+ uint num_types = 0;
+ for(uint t=0;t<child_types.size();t++){
+ if(child_types.at(t) == '<'){
+ num_types++;
+ }
+ }
+
+ string* types = new string[num_types];
+ string* ids = new string[num_types];
+ int type_idx = 0;
+ bool id_done = false;
+ for(uint t=0;t<child_types.size();t++){
+ if(child_types[t] == '<'){
+ id_done = false;
+ uint r;
+ for(r=t+1;child_types.at(r)!='>';r++){
+ if(r == child_types.size()){
+ cerr << "Parse error in child_types" << endl;
+ exit(EXIT_FAILURE);
+ }
+ if(child_types.at(r) == ' ') continue; //ignore whitespace
+ if(child_types.at(r) == ',') {id_done = true;continue;}
+ if(id_done == true)
+ types[type_idx].push_back(child_types.at(r));
+ else
+ ids[type_idx].push_back(child_types.at(r));
+ }
+ type_idx++;
+ t = r;
+ }
+ }
+
+ for(uint t=0;t<num_types;t++){
+ if(t==0)
+ sstr << " if(strcmp(" << child_selector << ", \"" << ids[t] << "\") == 0)" << endl;
+ else
+ sstr << " else if(strcmp(" << child_selector << ", \"" << ids[t] << "\") == 0)" << endl;
+ sstr << " m_" << var->cIdent() << "_vec[i] = new " << types[t] << tail.str() << endl;
+ }
+ }
+ else {
+ sstr << " m_" << var->cIdent() << "_vec[i] = new " << var->getType()->cIdent() << tail.str() << endl;
+ }
+
+ sstr << " assert(m_" << var->cIdent() << "_vec[i] != NULL);" << endl;
+ if (var->existPair("ordered")) {
+ string ordered = var->lookupPair("ordered");
+ sstr << " m_" << var->cIdent() << "_vec[i]->setOrdering(" << ordered << ");\n";
+ }
+ if (var->existPair("rank")) {
+ string rank = var->lookupPair("rank");
+ sstr << " m_" << var->cIdent() << "_vec[i]->setPriority(" << rank << ");\n";
+ }
+
+ // Set buffer size
+ if (var->getType()->isBuffer() && !var->existPair("infinite")) {
+ sstr << " if (FINITE_BUFFERING) {\n";
+ sstr << " m_" << var->cIdent() << "_vec[i]->setSize(PROCESSOR_BUFFER_SIZE);\n";
+ sstr << " }\n";
+ }
+
+ sstr << " }\n";
+ }
+ }
+
+ sstr << endl;
+
+ } else {
+ // Network port object
+ string network = var->lookupPair("network");
+ string ordered = var->lookupPair("ordered");
+ string vnet = var->lookupPair("virtual_network");
+
+ if (var->getMachine() != NULL) {
+ sstr << " m_" << var->cIdent() << "_vec.setSize(RubyConfig::numberOf"
+ << var->getMachine()->getIdent() << "PerChip(m_id));" << endl;
+ sstr << " for (int i = 0; i < RubyConfig::numberOf" << var->getMachine()->getIdent()
+ << "PerChip(m_id); i++) {" << endl;
+ sstr << " m_" << var->cIdent() << "_vec[i] = m_net_ptr->get"
+ << network << "NetQueue(i+m_id*RubyConfig::numberOf" <<var->getMachine()->getIdent()
+ << "PerChip()+MachineType_base_number(string_to_MachineType(\""
+ << var->getMachine()->getIdent() << "\")), "
+ << ordered << ", " << vnet << ");\n";
+ sstr << " assert(m_" << var->cIdent() << "_vec[i] != NULL);" << endl;
+ } else { // old protocol
+ sstr << " m_" << var->cIdent() << "_vec.setSize(1);" << endl;
+ sstr << " for (int i = 0; i < 1; i++) {" << endl;
+ sstr << " m_" << var->cIdent() << "_vec[i] = m_net_ptr->get"
+ << network << "NetQueue(m_id, "
+ << ordered << ", " << vnet << ");\n";
+ sstr << " assert(m_" << var->cIdent() << "_vec[i] != NULL);" << endl;
+ }
+
+ // Set ordering
+ if (var->existPair("ordered")) {
+ // A buffer
+ string ordered = var->lookupPair("ordered");
+ sstr << " m_" << var->cIdent() << "_vec[i]->setOrdering(" << ordered << ");\n";
+ }
+
+ // Set randomization
+ if (var->existPair("random")) {
+ // A buffer
+ string value = var->lookupPair("random");
+ sstr << " m_" << var->cIdent() << "_vec[i]->setRandomization(" << value << ");\n";
+ }
+
+ // Set Priority
+ if (var->existPair("rank")) {
+ string rank = var->lookupPair("rank");
+ sstr << " m_" << var->cIdent() << "_vec[i]->setPriority(" << rank << ");\n";
+ }
+
+ // Set buffer size
+ if (var->getType()->isBuffer()) {
+ sstr << " if (FINITE_BUFFERING) {\n";
+ sstr << " m_" << var->cIdent() << "_vec[i]->setSize(PROTOCOL_BUFFER_SIZE);\n";
+ sstr << " }\n";
+ }
+
+ sstr << " }\n";
+ }
+ }
+ }
+ // Look at all 'Machines'
+ for(int i=0; i<size; i++) {
+ StateMachine* machine = dynamic_cast<StateMachine*>(m_sym_vec[i]);
+ if (machine != NULL) {
+ string ident = machine->getIdent() + "_Controller";
+ sstr << " m_" << ident << "_vec.setSize(RubyConfig::numberOf" << machine->getIdent()
+ << "PerChip(m_id));" << endl;
+ sstr << " for (int i = 0; i < RubyConfig::numberOf" << machine->getIdent()
+ << "PerChip(m_id); i++) {" << endl;
+ sstr << " m_" << ident << "_vec[i] = new " << ident << "(this, i);\n";
+ sstr << " assert(m_" << ident << "_vec[i] != NULL);" << endl;
+ sstr << " }\n";
+ sstr << endl;
+ }
+ }
+
+ sstr << "}" << endl;
+ sstr << endl;
+ sstr << "Chip::~Chip()\n";
+ sstr << "{\n";
+
+// // FIXME: sequencer shouldn' be manually handled
+// sstr << " delete m_sequencer_ptr;" << endl;
+
+ // Look at all 'Vars'
+ for(int i=0; i<size; i++) {
+ Var* var = dynamic_cast<Var*>(m_sym_vec[i]);
+ if (var != NULL) {
+ if (var->existPair("chip_object")) {
+ if (var->existPair("no_chip_object")) {
+ // Do nothing
+ } else {
+ string template_hack = "";
+ if (var->existPair("template_hack")) {
+ template_hack = var->lookupPair("template_hack");
+ }
+ if (// var->getType()->existPair("cache") || var->getType()->existPair("tbe") ||
+// var->getType()->existPair("newtbe") || var->getType()->existPair("timer") ||
+// var->getType()->existPair("dir") || var->getType()->existPair("persistent") ||
+// var->getType()->existPair("filter") || var->existPair("trigger_queue")
+ var->existPair("no_vector")) {
+ sstr << " delete m_" << var->cIdent() << "_ptr;\n";
+ } else if ((var->getType()->existPair("mover")) && (var->getMachine()->getIdent() == "L2Cache")) {
+ sstr << " if (RubyConfig::isL2CacheDNUCAMoverChip(m_id)) {" << endl;
+ sstr << " delete m_" << var->cIdent() << "_ptr;\n";
+ sstr << " }\n";
+ } else if (var->getType()->existPair("mover") && ((var->getMachine()->getIdent() == "L1Cache") || (var->getMachine()->getIdent() == "Collector"))) {
+ sstr << " m_" << var->cIdent() << "_ptr = NULL;" << endl;
+ } else if (!var->existPair("network")) {
+ // Normal Object
+ sstr << " for (int i = 0; i < RubyConfig::numberOf" << var->getMachine()->getIdent()
+ << "PerChip(m_id); i++) {" << endl;
+ sstr << " delete m_" << var->cIdent() << "_vec[i];\n";
+ sstr << " }\n";
+ }
+ }
+ }
+ }
+ }
+
+ // Look at all 'Machines'
+ for(int i=0; i<size; i++) {
+ StateMachine* machine = dynamic_cast<StateMachine*>(m_sym_vec[i]);
+ if (machine != NULL) {
+ string ident = machine->getIdent() + "_Controller";
+ sstr << " for (int i = 0; i < RubyConfig::numberOf" << machine->getIdent()
+ << "PerChip(m_id); i++) {" << endl;
+ sstr << " delete m_" << ident << "_vec[i];\n";
+ sstr << " }\n";
+ }
+ }
+ sstr << "}\n";
+
+ sstr << "\n";
+ sstr << "void Chip::clearStats()\n";
+ sstr << "{\n";
+
+
+ // Look at all 'Machines'
+ for(int i=0; i<size; i++) {
+ StateMachine* machine = dynamic_cast<StateMachine*>(m_sym_vec[i]);
+ if (machine != NULL) {
+ string ident = machine->getIdent() + "_Controller";
+ sstr << " " << ident << "::clearStats();\n";
+ }
+ }
+
+ sstr << "}\n";
+
+ sstr << "\n";
+ sstr << "void Chip::printStats(ostream& out)\n";
+ sstr << "{\n";
+ sstr << " out << endl;\n";
+ sstr << " out << \"Chip Stats\" << endl;\n";
+ sstr << " out << \"----------\" << endl << endl;\n";
+
+ // Look at all 'Machines'
+ for(int i=0; i<size; i++) {
+ StateMachine* machine = dynamic_cast<StateMachine*>(m_sym_vec[i]);
+ if (machine != NULL) {
+ string ident = machine->getIdent() + "_Controller";
+ sstr << " " << ident << "::dumpStats(out);\n";
+ }
+ }
+
+ sstr << "}" << endl;
+ sstr << endl;
+ sstr << "void Chip::printConfig(ostream& out)\n";
+ sstr << "{\n";
+ sstr << " out << \"Chip Config\" << endl;\n";
+ sstr << " out << \"-----------\" << endl;\n";
+ sstr << " out << \"Total_Chips: \" << RubyConfig::numberOfChips() << endl;\n";
+
+ // Look at all 'Vars'
+ for(int i=0; i<size; i++) {
+ Var* var = dynamic_cast<Var*>(m_sym_vec[i]);
+ if (var != NULL) {
+ if (var->existPair("chip_object")) {
+ if (var->existPair("no_chip_object")) {
+ // Do nothing
+ } else {
+ string template_hack = "";
+ if (var->existPair("template_hack")) {
+ template_hack = var->lookupPair("template_hack");
+ }
+
+ if (!var->existPair("network") && (!var->getType()->existPair("primitive"))) {
+ // Normal Object
+ if (!var->getType()->existPair("non_obj") && (!var->getType()->isEnumeration())) {
+ if (var->existPair("no_vector")) {
+ sstr << " m_" << var->cIdent() << "_ptr->printConfig(out);\n";
+ } else {
+ sstr << " out << \"\\n" << var->cIdent() << " numberPerChip: \" << RubyConfig::numberOf" << var->getMachine()->getIdent()
+ << "PerChip() << endl;\n";
+ sstr << " m_" << var->cIdent() << "_vec[0]->printConfig(out);\n";
+// sstr << " for (int i = 0; i < RubyConfig::numberOf" << var->getMachine()->getIdent()
+// << "PerChip(m_id); i++) {" << endl;
+// sstr << " m_" << var->cIdent() << "_vec[i]->printConfig(out);\n";
+// sstr << " }\n";
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+
+ sstr << " out << endl;\n";
+ sstr << "}" << endl;
+
+ sstr << endl;
+ sstr << "void Chip::print(ostream& out) const\n";
+ sstr << "{\n";
+ sstr << " out << \"Ruby Chip\" << endl;\n";
+ sstr << "}" << endl;
+
+ sstr << "#ifdef CHECK_COHERENCE" << endl;
+ sstr << endl;
+ sstr << "bool Chip::isBlockShared(const Address& addr) const" << endl;
+ sstr << "{" << endl;
+
+ // Look at all 'Machines'
+ for(int i=0; i<size; i++) {
+ StateMachine* machine = dynamic_cast<StateMachine*>(m_sym_vec[i]);
+ if (machine != NULL) {
+ string ident = machine->getIdent() + "_Controller";
+ sstr << " for (int i = 0; i < RubyConfig::numberOf" << machine->getIdent()
+ << "PerChip(m_id); i++) {" << endl;
+ sstr << " if (m_" << ident << "_vec[i]->" << machine->getIdent() << "_isBlockShared(addr)) {\n";
+ sstr << " return true; \n";
+ sstr << " }\n";
+ sstr << " }\n";
+ }
+ }
+ sstr << " return false;" << endl;
+ sstr << "}" << endl;
+ sstr << endl;
+
+ sstr << endl;
+ sstr << "bool Chip::isBlockExclusive(const Address& addr) const" << endl;
+ sstr << "{" << endl;
+
+ // Look at all 'Machines'
+ for(int i=0; i<size; i++) {
+ StateMachine* machine = dynamic_cast<StateMachine*>(m_sym_vec[i]);
+ if (machine != NULL) {
+ string ident = machine->getIdent() + "_Controller";
+ sstr << " for (int i = 0; i < RubyConfig::numberOf" << machine->getIdent()
+ << "PerChip(m_id); i++) {" << endl;
+ sstr << " if (m_" << ident << "_vec[i]->" << machine->getIdent() << "_isBlockExclusive(addr)) {\n";
+ sstr << " return true; \n";
+ sstr << " }\n";
+ sstr << " }\n";
+ }
+ }
+
+ sstr << " return false;" << endl;
+ sstr << "}" << endl;
+ sstr << endl;
+
+ sstr << "#endif /* CHECK_COHERENCE */ " << endl;
+
+
+ sstr << endl;
+ sstr << "void Chip::dumpCaches(ostream& out) const" << endl;
+ sstr << "{" << endl;
+
+ // Look at all 'Vars'
+ for(int i=0; i<size; i++) {
+ Var* var = dynamic_cast<Var*>(m_sym_vec[i]);
+ if (var != NULL) {
+ if (var->getType()->existPair("cache")){ // caches are partitioned one per controller instaniation
+ sstr << " for (int i = 0; i < RubyConfig::numberOf" << var->getMachine()->getIdent()
+ << "PerChip(m_id); i++) {" << endl;
+ sstr << " m_" << var->cIdent() << "_vec[i]->print(out);\n";
+ sstr << " }\n";
+ }
+ }
+ }
+ sstr << "}" << endl;
+ sstr << endl;
+
+ // Function to dump cache tag and data information
+ sstr << "void Chip::dumpCacheData(ostream& out) const" << endl;
+ sstr << "{" << endl;
+
+ // Look at all 'Vars'
+ for(int i=0; i<size; i++) {
+ Var* var = dynamic_cast<Var*>(m_sym_vec[i]);
+ if (var != NULL) {
+ if (var->getType()->existPair("cache")){ // caches are partitioned one per controller instaniation
+ sstr << " for (int i = 0; i < RubyConfig::numberOf" << var->getMachine()->getIdent()
+ << "PerChip(m_id); i++) {" << endl;
+ sstr << " m_" << var->cIdent() << "_vec[i]->printData(out);\n";
+ sstr << " }\n";
+ }
+ }
+ }
+ sstr << "}" << endl;
+ sstr << endl;
+
+ sstr << "void Chip::recordCacheContents(CacheRecorder& tr) const" << endl;
+ sstr << "{" << endl;
+
+ // Look at all 'Vars'
+ for(int i=0; i<size; i++) {
+ Var* var = dynamic_cast<Var*>(m_sym_vec[i]);
+ if (var != NULL) {
+ if (var->getType()->existPair("cache")){ // caches are partitioned one per controller instaniation
+ sstr << " for (int i = 0; i < RubyConfig::numberOf" << var->getMachine()->getIdent()
+ << "PerChip(m_id); i++) {" << endl;
+ sstr << " m_" << var->cIdent() << "_vec[i]->recordCacheContents(tr);\n";
+ sstr << " }\n";
+ }
+ }
+ }
+ sstr << "}" << endl;
+
+ conditionally_write_file(path + "/Chip.cc", sstr);
+ }
+}
+
+Vector<StateMachine*> SymbolTable::getStateMachines() const
+{
+ Vector<StateMachine*> machine_vec;
+ int size = m_sym_vec.size();
+ for(int i=0; i<size; i++) {
+ StateMachine* type = dynamic_cast<StateMachine*>(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 << "<HTML></HTML>";
+ conditionally_write_file(path + "empty.html", out);
+ }
+
+ // Write all the symbols
+ int size = m_sym_vec.size();
+ for(int i=0; i<size; i++) {
+ m_sym_vec[i]->writeHTMLFiles(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<size; i++) {
+ ostringstream states, events, actions, transitions;
+ StateMachine* machine = dynamic_cast<StateMachine*>(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
new file mode 100644
index 000000000..8f40fe8c5
--- /dev/null
+++ b/src/mem/slicc/symbols/SymbolTable.hh
@@ -0,0 +1,121 @@
+
+/*
+ * 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.h
+ *
+ * Description:
+ *
+ * $Id$
+ *
+ * */
+
+#ifndef SYMBOLTABLE_H
+#define SYMBOLTABLE_H
+
+#include "slicc_global.hh"
+#include "Map.hh"
+#include "Vector.hh"
+
+#include "Symbol.hh"
+#include "Type.hh"
+#include "Var.hh"
+#include "Func.hh"
+#include "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<StateMachine*> 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 writeChipFiles(string path) const;
+
+ // Private copy constructor and assignment operator
+ SymbolTable(const SymbolTable& obj);
+ SymbolTable& operator=(const SymbolTable& obj);
+
+ // Data Members (m_ prefix)
+ Vector<Symbol*> m_sym_vec;
+ Vector<Map<string, Symbol*> > m_sym_map_vec;
+ Map<string, Map<string, Symbol*> > 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/Transition.cc b/src/mem/slicc/symbols/Transition.cc
new file mode 100644
index 000000000..7c144c101
--- /dev/null
+++ b/src/mem/slicc/symbols/Transition.cc
@@ -0,0 +1,173 @@
+
+/*
+ * 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 "Transition.hh"
+#include "State.hh"
+#include "Event.hh"
+#include "Action.hh"
+#include "util.hh"
+#include "Var.hh"
+
+Transition::Transition(string state, string event, string nextState,
+ const Vector<string>& actionList,
+ const Location& location,
+ const Map<string, string>& 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<State*>& states,
+ const Vector<Event*>& events,
+ const Vector<Action*>& 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; i<numActions; i++) {
+ str += m_actionPtrs[i]->getShorthand();
+ }
+ 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<Event*>& vec, string ident)
+{
+ int size = vec.size();
+ for(int i=0; i<size; i++) {
+ if (ident == vec[i]->getIdent()) {
+ return vec[i];
+ }
+ }
+ error("Event not found: " + ident);
+ return NULL;
+}
+
+State* Transition::findIndex(const Vector<State*>& vec, string ident)
+{
+ int size = vec.size();
+ for(int i=0; i<size; i++) {
+ if (ident == vec[i]->getIdent()) {
+ return vec[i];
+ }
+ }
+ error("State not found: " + ident);
+ return NULL;
+}
+
+Action* Transition::findIndex(const Vector<Action*>& vec, string ident)
+{
+ int size = vec.size();
+ for(int i=0; i<size; i++) {
+ if (ident == vec[i]->getIdent()) {
+ 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
new file mode 100644
index 000000000..af8eb3a05
--- /dev/null
+++ b/src/mem/slicc/symbols/Transition.hh
@@ -0,0 +1,120 @@
+
+/*
+ * 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.h
+ *
+ * Description:
+ *
+ * $Id$
+ *
+ * */
+
+#ifndef TRANSITION_H
+#define TRANSITION_H
+
+#include "slicc_global.hh"
+#include "Vector.hh"
+#include "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<string>& actionList,
+ const Location& location,
+ const Map<string, string>& 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<State*>& states,
+ const Vector<Event*>& events,
+ const Vector<Action*>& actions);
+
+ const string& getStateShorthand() const;
+ const string& getEventShorthand() const;
+ const string& getNextStateShorthand() const;
+ string getActionShorthands() const;
+ const Vector<Action*>& getActions() const { assert(m_actionPtrsValid); return m_actionPtrs; }
+ const Map<Var*, string>& 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<Event*>& vec, string ident);
+ State* findIndex(const Vector<State*>& vec, string ident);
+ Action* findIndex(const Vector<Action*>& 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<string> m_actionList;
+ Vector<Action*> m_actionPtrs;
+ Map<Var*, string> 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/Type.cc b/src/mem/slicc/symbols/Type.cc
new file mode 100644
index 000000000..a49e9d7ba
--- /dev/null
+++ b/src/mem/slicc/symbols/Type.cc
@@ -0,0 +1,746 @@
+
+/*
+ * 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 "Type.hh"
+#include "fileio.hh"
+#include "Map.hh"
+#include "StateMachine.hh"
+
+Type::Type(string id, const Location& location,
+ const Map<string, string>& 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<string, string>& 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<Type*>& 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<Type*>& 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<string, string> 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) const
+{
+ 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 \"Global.hh\"" << endl;
+ out << "#include \"Allocator.hh\"" << endl;
+ for (int i=0; i < size; i++) {
+ Type* type = m_data_member_type_vec[i];
+ if (!type->isPrimitive()) {
+ out << "#include \"" << type->cIdent() << ".hh" << "\"" << endl;
+ }
+ }
+ string interface = "";
+ if(existPair("interface")) {
+ interface = lookupPair("interface");
+ out << "#include \"" << 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;
+ }
+ 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;
+ }
+
+ }
+ out << " }" << endl;
+ } // end of if(!isGlobal())
+
+ // 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;
+ }
+ }
+
+ 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 \"" << 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 \"Global.hh\"" << endl;
+ if (m_isMachineType) {
+ out << "#include \"RubyConfig.hh\"" << endl << 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 << "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, NodeID 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 \"" << type_name << ".hh\"" << endl;
+ out << endl;
+
+ // Code for output operator
+ out << "ostream& operator<<(ostream& out, const " << type_name << "& obj)" << endl;
+ out << "{" << endl;
+ out << " out << " << type_name << "_to_string(obj);" << endl;
+ out << " out << flush;" << endl;
+ out << " return out;" << endl;
+ out << "}" << endl;
+
+ // Code to convert state to a string
+ out << endl;
+ out << "string " << type_name << "_to_string(const " << type_name << "& obj)" << endl;
+ out << "{" << endl;
+ out << " switch(obj) {" << endl;
+
+ // For each field
+ for( int i = 0; i<size; i++ ) {
+ out << " case " << type_name << "_" << m_enum_vec[i] << ":" << endl;
+ out << " return \"" << m_enum_vec[i] << "\";" << endl;
+ }
+
+ // Trailer
+ out << " default:" << endl;
+ out << " ERROR_MSG(\"Invalid range for type " << type_name << "\");" << endl;
+ out << " return \"\";" << endl;
+ out << " }" << endl;
+ out << "}" << endl;
+
+ // Code to convert from a string to the enumeration
+ out << endl;
+ out << type_name << " string_to_" << type_name << "(const string& str)" << endl;
+ out << "{" << endl;
+ out << " if (false) {" << endl;
+
+ // For each field
+ for( int i = 0; i<size; i++ ) {
+ out << " } else if (str == \"" << m_enum_vec[i] << "\") {" << endl;
+ out << " return " << type_name << "_" << m_enum_vec[i] << ";" << endl;
+ }
+
+ out << " } else {" << endl;
+ out << " WARN_EXPR(str);" << endl;
+ out << " ERROR_MSG(\"Invalid string conversion for type " << type_name << "\");" << endl;
+ out << " }" << endl;
+ out << "}" << endl;
+
+ // Code to increment an enumeration type
+ out << endl;
+ out << type_name << "& operator++( " << type_name << "& e) {" << endl;
+ out << " assert(e < " << type_name << "_NUM);" << endl;
+ out << " return e = " << type_name << "(e+1);" << endl;
+ out << "}" << endl;
+
+ // MachineType hack used to set the base level and number of components for each Machine
+ if (m_isMachineType) {
+ out << endl;
+ out << "/** \\brief returns the base vector index for each machine type to be used by NetDest " << endl;
+ out << " * " << endl;
+ out << " * \\return the base vector index for each machine type to be used by NetDest" << endl;
+ out << " * \\see NetDest.hh" << endl;
+ out << " */" << endl;
+ out << "int " << type_name << "_base_level(const " << type_name << "& obj)" << endl;
+ out << "{" << endl;
+ out << " switch(obj) {" << endl;
+
+ // For each field
+ Vector < string > MachineNames;
+ for( int i = 0; i<size; i++ ) {
+ out << " case " << type_name << "_" << m_enum_vec[i] << ":" << endl;
+ out << " return " << MachineNames.size() << ";" << endl;
+ MachineNames.insertAtBottom(m_enum_vec[i]);
+ }
+
+ // total num
+ out << " case " << type_name << "_NUM:" << endl;
+ out << " return " << MachineNames.size() << ";" << endl;
+
+ // Trailer
+ out << " default:" << endl;
+ out << " ERROR_MSG(\"Invalid range for type " << type_name << "\");" << endl;
+ out << " return -1;" << endl;
+ out << " }" << endl;
+ out << "}" << endl;
+
+ out << endl;
+ out << "/** \\brief The return value indicates the number of components created" << endl;
+ out << " * before a particular machine's components" << endl;
+ out << " * " << endl;
+ out << " * \\return the base number of components for each machine" << endl;
+ out << " */" << endl;
+ out << "int " << type_name << "_base_number(const " << type_name << "& obj)" << endl;
+ out << "{" << endl;
+ out << " switch(obj) {" << endl;
+
+ // For each field
+ MachineNames.clear();
+ for( int i = 0; i<size; i++ ) {
+ out << " case " << type_name << "_" << m_enum_vec[i] << ":" << endl;
+ out << " return 0";
+ for ( int m = 0; m<MachineNames.size(); m++) {
+ out << "+RubyConfig::numberOf" << MachineNames[m] << "()";
+ }
+ out << ";" << endl;
+ MachineNames.insertAtBottom(m_enum_vec[i]);
+ }
+
+ // total num
+ out << " case " << type_name << "_NUM:" << endl;
+ out << " return 0";
+ for ( int m = 0; m<MachineNames.size(); m++) {
+ out << "+RubyConfig::numberOf" << MachineNames[m] << "()";
+ }
+ out << ";" << endl;
+
+ // Trailer
+ out << " default:" << endl;
+ out << " ERROR_MSG(\"Invalid range for type " << type_name << "\");" << endl;
+ out << " return -1;" << endl;
+ out << " }" << endl;
+ out << "}" << endl;
+
+
+ out << endl;
+ out << "/** \\brief returns the total number of components for each machine" << endl;
+ out << " * \\return the total number of components for each machine" << endl;
+ out << " */" << endl;
+ out << "int " << type_name << "_base_count(const " << type_name << "& obj)" << endl;
+ out << "{" << endl;
+ out << " switch(obj) {" << endl;
+
+ // For each field
+ for( int i = 0; i<size; i++ ) {
+ out << " case " << type_name << "_" << m_enum_vec[i] << ":" << endl;
+ out << " return RubyConfig::numberOf" << m_enum_vec[i] << "();" << endl;
+ }
+
+ // total num
+ out << " case " << type_name << "_NUM:" << endl;
+ // Trailer
+ out << " default:" << endl;
+ out << " ERROR_MSG(\"Invalid range for type " << type_name << "\");" << endl;
+ out << " return -1;" << endl;
+ out << " }" << endl;
+ out << "}" << endl;
+
+ out << endl;
+ out << "/** \\brief returns the total number of components for each machine" << endl;
+ out << " * \\return the total number of components for each machine" << endl;
+ out << " */" << endl;
+ out << "int " << type_name << "_chip_count(const " << type_name << "& obj, NodeID chipID)" << endl;
+ out << "{" << endl;
+ out << " switch(obj) {" << endl;
+
+ // For each field
+ for( int i = 0; i<size; i++ ) {
+ out << " case " << type_name << "_" << m_enum_vec[i] << ":" << endl;
+ out << " return RubyConfig::numberOf" << m_enum_vec[i] << "PerChip(chipID);" << endl;
+ }
+
+ // total num
+ out << " case " << type_name << "_NUM:" << endl;
+ // Trailer
+ out << " default:" << endl;
+ out << " ERROR_MSG(\"Invalid range for type " << type_name << "\");" << endl;
+ out << " return -1;" << endl;
+ out << " }" << endl;
+ out << "}" << endl;
+
+
+ }
+
+ // Write the file
+ conditionally_write_file(path + type_name + ".cc", out);
+}
diff --git a/src/mem/slicc/symbols/Type.hh b/src/mem/slicc/symbols/Type.hh
new file mode 100644
index 000000000..c6f891326
--- /dev/null
+++ b/src/mem/slicc/symbols/Type.hh
@@ -0,0 +1,154 @@
+
+/*
+ * 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.h
+ *
+ * Description:
+ *
+ * $Id$
+ *
+ * */
+
+#ifndef TYPE_H
+#define TYPE_H
+
+#include "slicc_global.hh"
+#include "Map.hh"
+#include "Symbol.hh"
+
+class StateMachine;
+
+class Type : public Symbol {
+public:
+ // Constructors
+ Type(string id, const Location& location,
+ const Map<string, string>& 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"); }
+
+ // 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<string, string>& 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<Type*>& param_type_vec);
+ bool methodExist(string id) const { return m_method_return_type_map.exist(id); }
+
+ string methodId(string name, const Vector<Type*>& param_type_vec);
+ Type* methodReturnType(string id) const { return m_method_return_type_map.lookup(id); }
+ const Vector<Type*>& 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<string, string> pairs);
+ bool enumExist(string id) const { return m_enum_map.exist(id); }
+
+ // Write the C output files
+ void writeCFiles(string path) const;
+
+ 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<string, Type*> m_data_member_map;
+ Vector<string> m_data_member_ident_vec;
+ Vector<Type*> m_data_member_type_vec;
+ Vector<Map<string, string> > m_data_member_pairs_vec;
+ Vector<string*> m_data_member_init_code_vec;
+ // Needs pairs here
+
+ // Methods
+ Map<string, Type*> m_method_return_type_map;
+ Map<string, Vector<Type*> > m_method_param_type_map;
+ // Needs pairs here
+
+ // Enum
+ Map<string, bool> m_enum_map;
+ Vector<string> 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/Var.cc b/src/mem/slicc/symbols/Var.cc
new file mode 100644
index 000000000..a16c86967
--- /dev/null
+++ b/src/mem/slicc/symbols/Var.cc
@@ -0,0 +1,57 @@
+
+/*
+ * 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 "Var.hh"
+#include "StateMachine.hh"
+
+Var::Var(string id, const Location& location,
+ Type* type_ptr, string code,
+ const Map<string, string>& 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
new file mode 100644
index 000000000..277be0f74
--- /dev/null
+++ b/src/mem/slicc/symbols/Var.hh
@@ -0,0 +1,98 @@
+
+/*
+ * 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.h
+ *
+ * Description:
+ *
+ * $Id$
+ *
+ * */
+
+#ifndef VAR_H
+#define VAR_H
+
+#include "slicc_global.hh"
+#include "Symbol.hh"
+#include "Type.hh"
+
+class StateMachine;
+
+class Var : public Symbol {
+public:
+ // Constructors
+ Var(string id, const Location& location,
+ Type* type_ptr, string code,
+ const Map<string, string>& 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) const {}
+ 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