summaryrefslogtreecommitdiff
path: root/src/mem/slicc/symbols
diff options
context:
space:
mode:
authorNathan Binkert <nate@binkert.org>2009-05-11 10:38:43 -0700
committerNathan Binkert <nate@binkert.org>2009-05-11 10:38:43 -0700
commit2f30950143cc70bc42a3c8a4111d7cf8198ec881 (patch)
tree708f6c22edb3c6feb31dd82866c26623a5329580 /src/mem/slicc/symbols
parentc70241810d4e4f523f173c1646b008dc40faad8e (diff)
downloadgem5-2f30950143cc70bc42a3c8a4111d7cf8198ec881.tar.xz
ruby: Import ruby and slicc from GEMS
We eventually plan to replace the m5 cache hierarchy with the GEMS hierarchy, but for now we will make both live alongside eachother.
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