slicc: Change the code generation so that the generated code is easier to read

This commit is contained in:
Nathan Binkert 2010-03-12 18:42:56 -08:00
parent c8f296bca0
commit 0bbf63f17a
6 changed files with 261 additions and 122 deletions

View file

@ -54,8 +54,14 @@ class AST(PairContainer):
message = message % args message = message % args
code = self.slicc.codeFormatter() code = self.slicc.codeFormatter()
code(''' code('''
cerr << "Runtime Error at ${{self.location}}, Ruby Time: " << g_eventQueue_ptr->getTime() << ": "<< $message << ", PID: " << getpid() << endl; char c;
char c; cerr << "press return to continue." << endl; cin.get(c); abort(); cerr << "Runtime Error at ${{self.location}}, Ruby Time: "
<< g_eventQueue_ptr->getTime() << ": "
<< $message
<< ", PID: " << getpid() << endl
<< "press return to continue." << endl;
cin.get(c);
abort();
''') ''')
return code return code

View file

@ -59,10 +59,12 @@ class PeekStatementAST(StatementAST):
qcode = self.queue_name.var.code qcode = self.queue_name.var.code
code(''' code('''
{ {
// Declare message
const $mtid* in_msg_ptr; const $mtid* in_msg_ptr;
in_msg_ptr = dynamic_cast<const $mtid *>(($qcode).${{self.method}}()); in_msg_ptr = dynamic_cast<const $mtid *>(($qcode).${{self.method}}());
assert(in_msg_ptr != NULL); assert(in_msg_ptr != NULL); // Check the cast result
''') ''')
if self.pairs.has_key("block_on"): if self.pairs.has_key("block_on"):
address_field = self.pairs['block_on'] address_field = self.pairs['block_on']
code(''' code('''

View file

@ -29,9 +29,11 @@ from m5.util.code_formatter import code_formatter
def createSymbol(symbol, title): def createSymbol(symbol, title):
code = code_formatter() code = code_formatter()
code('''<HTML><BODY><BIG> code('''
$title: <HTML><BODY><BIG>
${{formatShorthand(symbol.short)}} - ${{symbol.desc}}</BIG></BODY></HTML>''') $title: ${{formatShorthand(symbol.short)}} - ${{symbol.desc}}
</BIG></BODY></HTML>
''')
return code return code
def formatShorthand(short): def formatShorthand(short):

View file

@ -95,7 +95,8 @@ class Func(Symbol):
params = ', '.join(self.param_strings) params = ', '.join(self.param_strings)
code(''' code('''
$return_type ${klass}::${{self.c_ident}}($params) $return_type
${klass}::${{self.c_ident}}($params)
{ {
${{self.body}} ${{self.body}}
} }

View file

@ -187,14 +187,14 @@ class $py_ident(RubyController):
self.message_buffer_names = [] self.message_buffer_names = []
code(''' code('''
/** \\file $ident.hh /** \\file $c_ident.hh
* *
* Auto generated C++ code started by $__file__:$__line__ * Auto generated C++ code started by $__file__:$__line__
* Created by slicc definition of Module "${{self.short}}" * Created by slicc definition of Module "${{self.short}}"
*/ */
#ifndef ${ident}_CONTROLLER_H #ifndef __${ident}_CONTROLLER_HH__
#define ${ident}_CONTROLLER_H #define __${ident}_CONTROLLER_HH__
#include <iostream> #include <iostream>
#include <sstream> #include <sstream>
@ -220,9 +220,11 @@ class $py_ident(RubyController):
code(''' code('''
extern std::stringstream ${ident}_transitionComment; extern std::stringstream ${ident}_transitionComment;
class $c_ident : public AbstractController { class $c_ident : public AbstractController
#ifdef CHECK_COHERENCE {
#endif /* CHECK_COHERENCE */ // the coherence checker needs to call isBlockExclusive() and isBlockShared()
// making the Chip a friend class is an easy way to do this for now
public: public:
typedef ${c_ident}Params Params; typedef ${c_ident}Params Params;
$c_ident(const Params *p); $c_ident(const Params *p);
@ -241,6 +243,7 @@ public:
void clearStats(); void clearStats();
void blockOnQueue(Address addr, MessageBuffer* port); void blockOnQueue(Address addr, MessageBuffer* port);
void unblock(Address addr); void unblock(Address addr);
private: private:
''') ''')
@ -255,8 +258,15 @@ private:
code(''' code('''
int m_number_of_TBEs; int m_number_of_TBEs;
TransitionResult doTransition(${ident}_Event event, ${ident}_State state, const Address& addr); // in ${ident}_Transitions.cc TransitionResult doTransition(${ident}_Event event,
TransitionResult doTransitionWorker(${ident}_Event event, ${ident}_State state, ${ident}_State& next_state, const Address& addr); // in ${ident}_Transitions.cc ${ident}_State state,
const Address& addr);
TransitionResult doTransitionWorker(${ident}_Event event,
${ident}_State state,
${ident}_State& next_state,
const Address& addr);
std::string m_name; std::string m_name;
int m_transitions_per_cycle; int m_transitions_per_cycle;
int m_buffer_size; int m_buffer_size;
@ -269,6 +279,7 @@ bool m_is_blocking;
map< Address, MessageBuffer* > m_block_map; map< Address, MessageBuffer* > m_block_map;
${ident}_Profiler s_profiler; ${ident}_Profiler s_profiler;
static int m_num_controllers; static int m_num_controllers;
// Internal functions // Internal functions
''') ''')
@ -288,7 +299,7 @@ static int m_num_controllers;
# the controller internal variables # the controller internal variables
code(''' code('''
// Object // Objects
''') ''')
for var in self.objects: for var in self.objects:
th = var.get("template_hack", "") th = var.get("template_hack", "")
@ -299,7 +310,7 @@ static int m_num_controllers;
code.dedent() code.dedent()
code('};') code('};')
code('#endif // ${ident}_CONTROLLER_H') code('#endif // __${ident}_CONTROLLER_H__')
code.write(path, '%s.hh' % c_ident) code.write(path, '%s.hh' % c_ident)
def printControllerCC(self, path): def printControllerCC(self, path):
@ -310,7 +321,7 @@ static int m_num_controllers;
c_ident = "%s_Controller" % self.ident c_ident = "%s_Controller" % self.ident
code(''' code('''
/** \\file $ident.cc /** \\file $c_ident.cc
* *
* Auto generated C++ code started by $__file__:$__line__ * Auto generated C++ code started by $__file__:$__line__
* Created by slicc definition of Module "${{self.short}}" * Created by slicc definition of Module "${{self.short}}"
@ -344,11 +355,12 @@ ${c_ident}Params::create()
return new $c_ident(this); return new $c_ident(this);
} }
int $c_ident::m_num_controllers = 0; int $c_ident::m_num_controllers = 0;
// for adding information to the protocol debug trace
stringstream ${ident}_transitionComment; stringstream ${ident}_transitionComment;
#define APPEND_TRANSITION_COMMENT(str) (${ident}_transitionComment << str) #define APPEND_TRANSITION_COMMENT(str) (${ident}_transitionComment << str)
/** \\brief constructor */ /** \\brief constructor */
$c_ident::$c_ident(const Params *p) $c_ident::$c_ident(const Params *p)
: AbstractController(p) : AbstractController(p)
@ -411,13 +423,18 @@ m_dma_sequencer_ptr->setController(this);
code(''' code('''
} }
void $c_ident::init() void
$c_ident::init()
{ {
MachineType machine_type;
int base;
m_machineID.type = MachineType_${ident}; m_machineID.type = MachineType_${ident};
m_machineID.num = m_version; m_machineID.num = m_version;
// Objects // initialize objects
s_profiler.setVersion(m_version); s_profiler.setVersion(m_version);
''') ''')
code.indent() code.indent()
@ -445,18 +462,16 @@ void $c_ident::init()
args = "m_number_of_TBEs" args = "m_number_of_TBEs"
else: else:
args = var.get("constructor_hack", "") args = var.get("constructor_hack", "")
args = "(%s)" % args
code('$expr$args;') code('$expr($args);')
else:
code(';')
code('assert($vid != NULL);') code('assert($vid != NULL);')
if "default" in var: if "default" in var:
code('(*$vid) = ${{var["default"]}}; // Object default') code('*$vid = ${{var["default"]}}; // Object default')
elif "default" in vtype: elif "default" in vtype:
code('(*$vid) = ${{vtype["default"]}}; // Type ${{vtype.ident}} default') comment = "Type %s default" % vtype.ident
code('*$vid = ${{vtype["default"]}}; // $comment')
# Set ordering # Set ordering
if "ordered" in var and "trigger_queue" not in var: if "ordered" in var and "trigger_queue" not in var:
@ -480,7 +495,9 @@ void $c_ident::init()
assert var.machine is not None assert var.machine is not None
code(''' code('''
$vid = m_net_ptr->get${network}NetQueue(m_version+MachineType_base_number(string_to_MachineType("${{var.machine.ident}}")), $ordered, $vnet); machine_type = string_to_MachineType("${{var.machine.ident}}");
base = MachineType_base_number(machine_type);
$vid = m_net_ptr->get${network}NetQueue(m_version + base, $ordered, $vnet);
''') ''')
code('assert($vid != NULL);') code('assert($vid != NULL);')
@ -508,7 +525,10 @@ if (m_buffer_size > 0) {
''') ''')
# set description (may be overriden later by port def) # set description (may be overriden later by port def)
code('$vid->setDescription("[Version " + int_to_string(m_version) + ", ${ident}, name=${{var.c_ident}}]");') code('''
$vid->setDescription("[Version " + int_to_string(m_version) + ", ${ident}, name=${{var.c_ident}}]");
''')
# Set the queue consumers # Set the queue consumers
code.insert_newline() code.insert_newline()
@ -553,51 +573,77 @@ if (m_buffer_size > 0) {
mq_ident = "NULL" mq_ident = "NULL"
code(''' code('''
int $c_ident::getNumControllers() { int
$c_ident::getNumControllers()
{
return m_num_controllers; return m_num_controllers;
} }
MessageBuffer* $c_ident::getMandatoryQueue() const { MessageBuffer*
$c_ident::getMandatoryQueue() const
{
return $mq_ident; return $mq_ident;
} }
const int & $c_ident::getVersion() const{ const int &
$c_ident::getVersion() const
{
return m_version; return m_version;
} }
const string $c_ident::toString() const{ const string
$c_ident::toString() const
{
return "$c_ident"; return "$c_ident";
} }
const string $c_ident::getName() const{ const string
$c_ident::getName() const
{
return m_name; return m_name;
} }
const MachineType $c_ident::getMachineType() const{
const MachineType
$c_ident::getMachineType() const
{
return MachineType_${ident}; return MachineType_${ident};
} }
void $c_ident::blockOnQueue(Address addr, MessageBuffer* port) { void
$c_ident::blockOnQueue(Address addr, MessageBuffer* port)
{
m_is_blocking = true; m_is_blocking = true;
m_block_map[addr] = port; m_block_map[addr] = port;
} }
void $c_ident::unblock(Address addr) {
void
$c_ident::unblock(Address addr)
{
m_block_map.erase(addr); m_block_map.erase(addr);
if (m_block_map.size() == 0) { if (m_block_map.size() == 0) {
m_is_blocking = false; m_is_blocking = false;
} }
} }
void $c_ident::print(ostream& out) const { out << "[$c_ident " << m_version << "]"; } void
$c_ident::print(ostream& out) const
{
out << "[$c_ident " << m_version << "]";
}
void $c_ident::printConfig(ostream& out) const { void
$c_ident::printConfig(ostream& out) const
{
out << "$c_ident config: " << m_name << endl; out << "$c_ident config: " << m_name << endl;
out << " version: " << m_version << endl; out << " version: " << m_version << endl;
for (map<string, string>::const_iterator it = m_cfg.begin(); it != m_cfg.end(); it++) { map<string, string>::const_iterator it;
out << " " << (*it).first << ": " << (*it).second << endl; for (it = m_cfg.begin(); it != m_cfg.end(); it++)
} out << " " << it->first << ": " << it->second << endl;
} }
void $c_ident::printStats(ostream& out) const { void
$c_ident::printStats(ostream& out) const
{
''') ''')
# #
# Cache and Memory Controllers have specific profilers associated with # Cache and Memory Controllers have specific profilers associated with
@ -638,7 +684,8 @@ void $c_ident::clearStats() {
code(''' code('''
/** \\brief ${{action.desc}} */ /** \\brief ${{action.desc}} */
void $c_ident::${{action.ident}}(const Address& addr) void
$c_ident::${{action.ident}}(const Address& addr)
{ {
DEBUG_MSG(GENERATED_COMP, HighPrio, "executing"); DEBUG_MSG(GENERATED_COMP, HighPrio, "executing");
${{action["c_code"]}} ${{action["c_code"]}}
@ -657,6 +704,7 @@ void $c_ident::${{action.ident}}(const Address& addr)
// Auto generated C++ code started by $__file__:$__line__ // Auto generated C++ code started by $__file__:$__line__
// ${ident}: ${{self.short}} // ${ident}: ${{self.short}}
#include "base/misc.hh"
#include "mem/ruby/common/Global.hh" #include "mem/ruby/common/Global.hh"
#include "mem/ruby/slicc_interface/RubySlicc_includes.hh" #include "mem/ruby/slicc_interface/RubySlicc_includes.hh"
#include "mem/protocol/${ident}_Controller.hh" #include "mem/protocol/${ident}_Controller.hh"
@ -665,16 +713,22 @@ void $c_ident::${{action.ident}}(const Address& addr)
#include "mem/protocol/Types.hh" #include "mem/protocol/Types.hh"
#include "mem/ruby/system/System.hh" #include "mem/ruby/system/System.hh"
void ${ident}_Controller::wakeup() void
${ident}_Controller::wakeup()
{ {
// DEBUG_EXPR(GENERATED_COMP, MedPrio, *this);
// DEBUG_EXPR(GENERATED_COMP, MedPrio, g_eventQueue_ptr->getTime());
int counter = 0; int counter = 0;
while (true) { while (true) {
// Some cases will put us into an infinite loop without this limit // Some cases will put us into an infinite loop without this limit
assert(counter <= m_transitions_per_cycle); assert(counter <= m_transitions_per_cycle);
if (counter == m_transitions_per_cycle) { if (counter == m_transitions_per_cycle) {
g_system_ptr->getProfiler()->controllerBusy(m_machineID); // Count how often we\'re fully utilized // Count how often we are fully utilized
g_eventQueue_ptr->scheduleEvent(this, 1); // Wakeup in another cycle and try again g_system_ptr->getProfiler()->controllerBusy(m_machineID);
// Wakeup in another cycle and try again
g_eventQueue_ptr->scheduleEvent(this, 1);
break; break;
} }
''') ''')
@ -697,6 +751,8 @@ void ${ident}_Controller::wakeup()
code(''' code('''
break; // If we got this far, we have nothing left todo break; // If we got this far, we have nothing left todo
} }
// g_eventQueue_ptr->scheduleEvent(this, 1);
// DEBUG_NEWLINE(GENERATED_COMP, MedPrio);
} }
''') ''')
@ -724,8 +780,10 @@ void ${ident}_Controller::wakeup()
#define GET_TRANSITION_COMMENT() (${ident}_transitionComment.str()) #define GET_TRANSITION_COMMENT() (${ident}_transitionComment.str())
#define CLEAR_TRANSITION_COMMENT() (${ident}_transitionComment.str("")) #define CLEAR_TRANSITION_COMMENT() (${ident}_transitionComment.str(""))
TransitionResult ${ident}_Controller::doTransition(${ident}_Event event, ${ident}_State state, const Address& addr TransitionResult
) ${ident}_Controller::doTransition(${ident}_Event event,
${ident}_State state,
const Address &addr)
{ {
${ident}_State next_state = state; ${ident}_State next_state = state;
@ -736,24 +794,28 @@ TransitionResult ${ident}_Controller::doTransition(${ident}_Event event, ${ident
DEBUG_EXPR(GENERATED_COMP, MedPrio,event); DEBUG_EXPR(GENERATED_COMP, MedPrio,event);
DEBUG_EXPR(GENERATED_COMP, MedPrio,addr); DEBUG_EXPR(GENERATED_COMP, MedPrio,addr);
TransitionResult result = doTransitionWorker(event, state, next_state, addr); TransitionResult result =
doTransitionWorker(event, state, next_state, addr);
if (result == TransitionResult_Valid) { if (result == TransitionResult_Valid) {
DEBUG_EXPR(GENERATED_COMP, MedPrio, next_state); DEBUG_EXPR(GENERATED_COMP, MedPrio, next_state);
DEBUG_NEWLINE(GENERATED_COMP, MedPrio); DEBUG_NEWLINE(GENERATED_COMP, MedPrio);
s_profiler.countTransition(state, event); s_profiler.countTransition(state, event);
if (Debug::getProtocolTrace()) { if (Debug::getProtocolTrace()) {
g_system_ptr->getProfiler()->profileTransition("${ident}", m_version, addr, g_system_ptr->getProfiler()->profileTransition("${ident}",
m_version, addr,
${ident}_State_to_string(state), ${ident}_State_to_string(state),
${ident}_Event_to_string(event), ${ident}_Event_to_string(event),
${ident}_State_to_string(next_state), GET_TRANSITION_COMMENT()); ${ident}_State_to_string(next_state),
GET_TRANSITION_COMMENT());
} }
CLEAR_TRANSITION_COMMENT(); CLEAR_TRANSITION_COMMENT();
${ident}_setState(addr, next_state); ${ident}_setState(addr, next_state);
} else if (result == TransitionResult_ResourceStall) { } else if (result == TransitionResult_ResourceStall) {
if (Debug::getProtocolTrace()) { if (Debug::getProtocolTrace()) {
g_system_ptr->getProfiler()->profileTransition("${ident}", m_version, addr, g_system_ptr->getProfiler()->profileTransition("${ident}",
m_version, addr,
${ident}_State_to_string(state), ${ident}_State_to_string(state),
${ident}_Event_to_string(event), ${ident}_Event_to_string(event),
${ident}_State_to_string(next_state), ${ident}_State_to_string(next_state),
@ -763,7 +825,8 @@ TransitionResult ${ident}_Controller::doTransition(${ident}_Event event, ${ident
DEBUG_MSG(GENERATED_COMP, HighPrio, "stalling"); DEBUG_MSG(GENERATED_COMP, HighPrio, "stalling");
DEBUG_NEWLINE(GENERATED_COMP, MedPrio); DEBUG_NEWLINE(GENERATED_COMP, MedPrio);
if (Debug::getProtocolTrace()) { if (Debug::getProtocolTrace()) {
g_system_ptr->getProfiler()->profileTransition("${ident}", m_version, addr, g_system_ptr->getProfiler()->profileTransition("${ident}",
m_version, addr,
${ident}_State_to_string(state), ${ident}_State_to_string(state),
${ident}_Event_to_string(event), ${ident}_Event_to_string(event),
${ident}_State_to_string(next_state), ${ident}_State_to_string(next_state),
@ -774,8 +837,11 @@ TransitionResult ${ident}_Controller::doTransition(${ident}_Event event, ${ident
return result; return result;
} }
TransitionResult ${ident}_Controller::doTransitionWorker(${ident}_Event event, ${ident}_State state, ${ident}_State& next_state, const Address& addr TransitionResult
) ${ident}_Controller::doTransitionWorker(${ident}_Event event,
${ident}_State state,
${ident}_State& next_state,
const Address& addr)
{ {
switch(HASH_FUN(state, event)) { switch(HASH_FUN(state, event)) {
''') ''')
@ -801,9 +867,8 @@ TransitionResult ${ident}_Controller::doTransitionWorker(${ident}_Event event, $
for key,val in res.iteritems(): for key,val in res.iteritems():
if key.type.ident != "DNUCAStopTable": if key.type.ident != "DNUCAStopTable":
val = ''' val = '''
if (!%s.areNSlotsAvailable(%s)) { if (!%s.areNSlotsAvailable(%s))
return TransitionResult_ResourceStall; return TransitionResult_ResourceStall;
}
''' % (key.code, val) ''' % (key.code, val)
case_sorter.append(val) case_sorter.append(val)
@ -843,9 +908,7 @@ if (!%s.areNSlotsAvailable(%s)) {
# the same code # the same code
for trans in transitions: for trans in transitions:
code(' case HASH_FUN($trans):') code(' case HASH_FUN($trans):')
code(' {')
code(' $case') code(' $case')
code(' }')
code(''' code('''
default: default:
@ -869,8 +932,8 @@ if (!%s.areNSlotsAvailable(%s)) {
// Auto generated C++ code started by $__file__:$__line__ // Auto generated C++ code started by $__file__:$__line__
// ${ident}: ${{self.short}} // ${ident}: ${{self.short}}
#ifndef ${ident}_PROFILER_H #ifndef __${ident}_PROFILER_HH_
#define ${ident}_PROFILER_H #define __${ident}_PROFILER_HH_
#include <iostream> #include <iostream>
@ -878,7 +941,8 @@ if (!%s.areNSlotsAvailable(%s)) {
#include "mem/protocol/${ident}_State.hh" #include "mem/protocol/${ident}_State.hh"
#include "mem/protocol/${ident}_Event.hh" #include "mem/protocol/${ident}_Event.hh"
class ${ident}_Profiler { class ${ident}_Profiler
{
public: public:
${ident}_Profiler(); ${ident}_Profiler();
void setVersion(int version); void setVersion(int version);
@ -894,7 +958,7 @@ class ${ident}_Profiler {
int m_version; int m_version;
}; };
#endif // ${ident}_PROFILER_H #endif // __${ident}_PROFILER_HH__
''') ''')
code.write(path, "%s_Profiler.hh" % self.ident) code.write(path, "%s_Profiler.hh" % self.ident)
@ -920,11 +984,15 @@ ${ident}_Profiler::${ident}_Profiler()
m_event_counters[event] = 0; m_event_counters[event] = 0;
} }
} }
void ${ident}_Profiler::setVersion(int version)
void
${ident}_Profiler::setVersion(int version)
{ {
m_version = version; m_version = version;
} }
void ${ident}_Profiler::clearStats()
void
${ident}_Profiler::clearStats()
{ {
for (int state = 0; state < ${ident}_State_NUM; state++) { for (int state = 0; state < ${ident}_State_NUM; state++) {
for (int event = 0; event < ${ident}_Event_NUM; event++) { for (int event = 0; event < ${ident}_Event_NUM; event++) {
@ -936,17 +1004,22 @@ void ${ident}_Profiler::clearStats()
m_event_counters[event] = 0; m_event_counters[event] = 0;
} }
} }
void ${ident}_Profiler::countTransition(${ident}_State state, ${ident}_Event event) void
${ident}_Profiler::countTransition(${ident}_State state, ${ident}_Event event)
{ {
assert(m_possible[state][event]); assert(m_possible[state][event]);
m_counters[state][event]++; m_counters[state][event]++;
m_event_counters[event]++; m_event_counters[event]++;
} }
void ${ident}_Profiler::possibleTransition(${ident}_State state, ${ident}_Event event) void
${ident}_Profiler::possibleTransition(${ident}_State state,
${ident}_Event event)
{ {
m_possible[state][event] = true; m_possible[state][event] = true;
} }
void ${ident}_Profiler::dumpStats(std::ostream& out) const
void
${ident}_Profiler::dumpStats(std::ostream& out) const
{ {
using namespace std; using namespace std;
@ -962,7 +1035,8 @@ void ${ident}_Profiler::dumpStats(std::ostream& out) const
for (int event = 0; event < ${ident}_Event_NUM; event++) { for (int event = 0; event < ${ident}_Event_NUM; event++) {
if (m_possible[state][event]) { if (m_possible[state][event]) {
int count = m_counters[state][event]; int count = m_counters[state][event];
out << (${ident}_State) state << " " << (${ident}_Event) event << " " << count; out << (${ident}_State) state << " "
<< (${ident}_Event) event << " " << count;
if (count == 0) { if (count == 0) {
out << " <-- "; out << " <-- ";
} }
@ -978,10 +1052,14 @@ void ${ident}_Profiler::dumpStats(std::ostream& out) const
# ************************** # **************************
# ******* HTML Files ******* # ******* HTML Files *******
# ************************** # **************************
def frameRef(self, click_href, click_target, over_href, over_target_num, def frameRef(self, click_href, click_target, over_href, over_num, text):
text):
code = self.symtab.codeFormatter(fix_newlines=False) code = self.symtab.codeFormatter(fix_newlines=False)
code("""<A href=\"$click_href\" target=\"$click_target\" onMouseOver=\"if (parent.frames[$over_target_num].location != parent.location + '$over_href') { parent.frames[$over_target_num].location='$over_href' }\" >${{html.formatShorthand(text)}}</A>""") code("""<A href=\"$click_href\" target=\"$click_target\" onmouseover=\"
if (parent.frames[$over_num].location != parent.location + '$over_href') {
parent.frames[$over_num].location='$over_href'
}\">
${{html.formatShorthand(text)}}
</A>""")
return str(code) return str(code)
def writeHTMLFiles(self, path): def writeHTMLFiles(self, path):
@ -1014,7 +1092,8 @@ void ${ident}_Profiler::dumpStats(std::ostream& out) const
code = self.symtab.codeFormatter() code = self.symtab.codeFormatter()
code(''' code('''
<HTML><BODY link="blue" vlink="blue"> <HTML>
<BODY link="blue" vlink="blue">
<H1 align="center">${{html.formatShorthand(self.short)}}: <H1 align="center">${{html.formatShorthand(self.short)}}:
''') ''')
@ -1098,13 +1177,12 @@ void ${ident}_Profiler::dumpStats(std::ostream& out) const
else: else:
color = "white" color = "white"
fix = code.nofix()
code('<TD bgcolor=$color>') code('<TD bgcolor=$color>')
for action in trans.actions: for action in trans.actions:
href = "%s_action_%s.html" % (self.ident, action.ident) href = "%s_action_%s.html" % (self.ident, action.ident)
ref = self.frameRef(href, "Status", href, "1", ref = self.frameRef(href, "Status", href, "1",
action.short) action.short)
code(' $ref\n') code(' $ref')
if next != state: if next != state:
if trans.actions: if trans.actions:
code('/') code('/')
@ -1112,8 +1190,7 @@ void ${ident}_Profiler::dumpStats(std::ostream& out) const
over = "%s_State_%s.html" % (self.ident, next.ident) over = "%s_State_%s.html" % (self.ident, next.ident)
ref = self.frameRef(click, "Table", over, "1", next.short) ref = self.frameRef(click, "Table", over, "1", next.short)
code("$ref") code("$ref")
code("</TD>\n") code("</TD>")
code.fix(fix)
# -- Each row # -- Each row
if state == active_state: if state == active_state:
@ -1129,6 +1206,7 @@ void ${ident}_Profiler::dumpStats(std::ostream& out) const
</TR> </TR>
''') ''')
code(''' code('''
<!- Column footer->
<TR> <TR>
<TH> </TH> <TH> </TH>
''') ''')

View file

@ -199,8 +199,8 @@ class Type(Symbol):
* Auto generated C++ code started by $__file__:$__line__ * Auto generated C++ code started by $__file__:$__line__
*/ */
#ifndef ${{self.c_ident}}_H #ifndef __${{self.c_ident}}_HH__
#define ${{self.c_ident}}_H #define __${{self.c_ident}}_HH__
#include <iostream> #include <iostream>
@ -218,17 +218,14 @@ class Type(Symbol):
parent = " : public %s" % self["interface"] parent = " : public %s" % self["interface"]
code(''' code('''
$klass ${{self.c_ident}}$parent { $klass ${{self.c_ident}}$parent
{
public: public:
${{self.c_ident}}() ${{self.c_ident}}()
{
''', klass="class") ''', klass="class")
# Call superclass constructor
if "interface" in self:
code(' : ${{self["interface"]}}()')
code.indent() code.indent()
code("{")
if not self.isGlobal: if not self.isGlobal:
code.indent() code.indent()
for dm in self.data_members.values(): for dm in self.data_members.values():
@ -245,9 +242,6 @@ $klass ${{self.c_ident}}$parent {
code.dedent() code.dedent()
code('}') code('}')
# ******** Default destructor ********
code('~${{self.c_ident}}() { };')
# ******** Full init constructor ******** # ******** Full init constructor ********
if not self.isGlobal: if not self.isGlobal:
params = [ 'const %s& local_%s' % (dm.type.c_ident, dm.ident) \ params = [ 'const %s& local_%s' % (dm.type.c_ident, dm.ident) \
@ -279,7 +273,9 @@ $klass ${{self.c_ident}}$parent {
# create a static factory method # create a static factory method
if "interface" in self: if "interface" in self:
code(''' code('''
static ${{self["interface"]}}* create() { static ${{self["interface"]}}*
create()
{
return new ${{self.c_ident}}(); return new ${{self.c_ident}}();
} }
''') ''')
@ -290,10 +286,29 @@ static ${{self["interface"]}}* create() {
if self.isMessage: if self.isMessage:
code(''' code('''
Message* clone() const { checkAllocator(); return s_allocator_ptr->allocate(*this); } Message *
void destroy() { checkAllocator(); s_allocator_ptr->deallocate(this); } clone() const
{
checkAllocator();
return s_allocator_ptr->allocate(*this);
}
void
destroy()
{
checkAllocator();
s_allocator_ptr->deallocate(this);
}
static Allocator<${{self.c_ident}}>* s_allocator_ptr; static Allocator<${{self.c_ident}}>* s_allocator_ptr;
static void checkAllocator() { if (s_allocator_ptr == NULL) { s_allocator_ptr = new Allocator<${{self.c_ident}}>; }}
static void
checkAllocator()
{
if (s_allocator_ptr == NULL) {
s_allocator_ptr = new Allocator<${{self.c_ident}}>;
}
}
''') ''')
if not self.isGlobal: if not self.isGlobal:
@ -304,7 +319,11 @@ static void checkAllocator() { if (s_allocator_ptr == NULL) { s_allocator_ptr =
/** \\brief Const accessor method for ${{dm.ident}} field. /** \\brief Const accessor method for ${{dm.ident}} field.
* \\return ${{dm.ident}} field * \\return ${{dm.ident}} field
*/ */
const ${{dm.type.c_ident}}& get${{dm.ident}}() const { return m_${{dm.ident}}; } const ${{dm.type.c_ident}}&
get${{dm.ident}}() const
{
return m_${{dm.ident}};
}
''') ''')
# Non-const Get methods for each field # Non-const Get methods for each field
@ -314,7 +333,11 @@ const ${{dm.type.c_ident}}& get${{dm.ident}}() const { return m_${{dm.ident}}; }
/** \\brief Non-const accessor method for ${{dm.ident}} field. /** \\brief Non-const accessor method for ${{dm.ident}} field.
* \\return ${{dm.ident}} field * \\return ${{dm.ident}} field
*/ */
${{dm.type.c_ident}}& get${{dm.ident}}() { return m_${{dm.ident}}; } ${{dm.type.c_ident}}&
get${{dm.ident}}()
{
return m_${{dm.ident}};
}
''') ''')
#Set methods for each field #Set methods for each field
@ -322,7 +345,11 @@ ${{dm.type.c_ident}}& get${{dm.ident}}() { return m_${{dm.ident}}; }
for dm in self.data_members.values(): for dm in self.data_members.values():
code(''' code('''
/** \\brief Mutator method for ${{dm.ident}} field */ /** \\brief Mutator method for ${{dm.ident}} field */
void set${{dm.ident}}(const ${{dm.type.c_ident}}& local_${{dm.ident}}) { m_${{dm.ident}} = local_${{dm.ident}}; } void
set${{dm.ident}}(const ${{dm.type.c_ident}}& local_${{dm.ident}})
{
m_${{dm.ident}} = local_${{dm.ident}};
}
''') ''')
code('void print(std::ostream& out) const;') code('void print(std::ostream& out) const;')
@ -346,11 +373,10 @@ void set${{dm.ident}}(const ${{dm.type.c_ident}}& local_${{dm.ident}}) { m_${{dm
assert self.isGlobal assert self.isGlobal
init = " = %s" % (dm.init_code) init = " = %s" % (dm.init_code)
desc = ""
if "desc" in dm: if "desc" in dm:
desc = '/**< %s */' % dm["desc"] code('/** ${{dm["desc"]}} */')
code('$const${{dm.type.c_ident}} m_${{dm.ident}}$init; $desc') code('$const${{dm.type.c_ident}} m_${{dm.ident}}$init;')
if self.isMessage: if self.isMessage:
code('unsigned proc_id;') code('unsigned proc_id;')
@ -360,18 +386,19 @@ void set${{dm.ident}}(const ${{dm.type.c_ident}}& local_${{dm.ident}}) { m_${{dm
code(''' code('''
// Output operator declaration // Output operator declaration
std::ostream& operator<<(std::ostream& out, const ${{self.c_ident}}& obj); std::ostream&
operator<<(std::ostream& out, const ${{self.c_ident}}& obj);
// Output operator definition // Output operator definition
extern inline extern inline std::ostream&
std::ostream& operator<<(std::ostream& out, const ${{self.c_ident}}& obj) operator<<(std::ostream& out, const ${{self.c_ident}}& obj)
{ {
obj.print(out); obj.print(out);
out << std::flush; out << std::flush;
return out; return out;
} }
#endif // ${{self.c_ident}}_H #endif // __${{self.c_ident}}_HH__
''') ''')
code.write(path, "%s.hh" % self.c_ident) code.write(path, "%s.hh" % self.c_ident)
@ -396,7 +423,8 @@ using namespace std;
code('Allocator<${{self.c_ident}}>* ${{self.c_ident}}::s_allocator_ptr = NULL;') code('Allocator<${{self.c_ident}}>* ${{self.c_ident}}::s_allocator_ptr = NULL;')
code(''' code('''
/** \\brief Print the state of this object */ /** \\brief Print the state of this object */
void ${{self.c_ident}}::print(ostream& out) const void
${{self.c_ident}}::print(ostream& out) const
{ {
out << "[${{self.c_ident}}: "; out << "[${{self.c_ident}}: ";
''') ''')
@ -424,14 +452,16 @@ void ${{self.c_ident}}::print(ostream& out) const
* *
* Auto generated C++ code started by $__file__:$__line__ * Auto generated C++ code started by $__file__:$__line__
*/ */
#ifndef ${{self.c_ident}}_H
#define ${{self.c_ident}}_H #ifndef __${{self.c_ident}}_HH__
#define __${{self.c_ident}}_HH__
#include <iostream> #include <iostream>
#include <string> #include <string>
#include "mem/ruby/common/Global.hh" #include "mem/ruby/common/Global.hh"
// Class definition
/** \\enum ${{self.c_ident}} /** \\enum ${{self.c_ident}}
* \\brief ${{self.desc}} * \\brief ${{self.desc}}
*/ */
@ -452,8 +482,14 @@ enum ${{self.c_ident}} {
code(''' code('''
${{self.c_ident}}_NUM ${{self.c_ident}}_NUM
}; };
// Code to convert from a string to the enumeration
${{self.c_ident}} string_to_${{self.c_ident}}(const std::string& str); ${{self.c_ident}} string_to_${{self.c_ident}}(const std::string& str);
// Code to convert state to a string
std::string ${{self.c_ident}}_to_string(const ${{self.c_ident}}& obj); std::string ${{self.c_ident}}_to_string(const ${{self.c_ident}}& obj);
// Code to increment an enumeration type
${{self.c_ident}} &operator++(${{self.c_ident}} &e); ${{self.c_ident}} &operator++(${{self.c_ident}} &e);
''') ''')
@ -473,7 +509,7 @@ int ${{self.c_ident}}_base_count(const ${{self.c_ident}}& obj);
code(''' code('''
std::ostream& operator<<(std::ostream& out, const ${{self.c_ident}}& obj); std::ostream& operator<<(std::ostream& out, const ${{self.c_ident}}& obj);
#endif // ${{self.c_ident}}_H #endif // __${{self.c_ident}}_HH__
''') ''')
code.write(path, "%s.hh" % self.c_ident) code.write(path, "%s.hh" % self.c_ident)
@ -500,14 +536,18 @@ using namespace std;
code('#include "mem/protocol/${{enum.ident}}_Controller.hh"') code('#include "mem/protocol/${{enum.ident}}_Controller.hh"')
code(''' code('''
ostream& operator<<(ostream& out, const ${{self.c_ident}}& obj) // Code for output operator
ostream&
operator<<(ostream& out, const ${{self.c_ident}}& obj)
{ {
out << ${{self.c_ident}}_to_string(obj); out << ${{self.c_ident}}_to_string(obj);
out << flush; out << flush;
return out; return out;
} }
string ${{self.c_ident}}_to_string(const ${{self.c_ident}}& obj) // Code to convert state to a string
string
${{self.c_ident}}_to_string(const ${{self.c_ident}}& obj)
{ {
switch(obj) { switch(obj) {
''') ''')
@ -527,17 +567,19 @@ string ${{self.c_ident}}_to_string(const ${{self.c_ident}}& obj)
} }
} }
${{self.c_ident}} string_to_${{self.c_ident}}(const string& str) // Code to convert from a string to the enumeration
${{self.c_ident}}
string_to_${{self.c_ident}}(const string& str)
{ {
''') ''')
# For each field # For each field
start = ""
code.indent() code.indent()
code("if (false) {")
start = "} else "
for enum in self.enums.itervalues(): for enum in self.enums.itervalues():
code('${start}if (str == "${{enum.ident}}") {') code('${start}if (str == "${{enum.ident}}") {')
code(' return ${{self.c_ident}}_${{enum.ident}};') code(' return ${{self.c_ident}}_${{enum.ident}};')
start = "} else "
code.dedent() code.dedent()
code(''' code('''
@ -547,7 +589,10 @@ ${{self.c_ident}} string_to_${{self.c_ident}}(const string& str)
} }
} }
${{self.c_ident}}& operator++(${{self.c_ident}}& e) { // Code to increment an enumeration type
${{self.c_ident}}&
operator++(${{self.c_ident}}& e)
{
assert(e < ${{self.c_ident}}_NUM); assert(e < ${{self.c_ident}}_NUM);
return e = ${{self.c_ident}}(e+1); return e = ${{self.c_ident}}(e+1);
} }
@ -557,12 +602,14 @@ ${{self.c_ident}}& operator++(${{self.c_ident}}& e) {
# components for each Machine # components for each Machine
if self.isMachineType: if self.isMachineType:
code(''' code('''
/** \\brief returns the base vector index for each machine type to be used by NetDest /** \\brief returns the base vector index for each machine type to be
* used by NetDest
* *
* \\return the base vector index for each machine type to be used by NetDest * \\return the base vector index for each machine type to be used by NetDest
* \\see NetDest.hh * \\see NetDest.hh
*/ */
int ${{self.c_ident}}_base_level(const ${{self.c_ident}}& obj) int
${{self.c_ident}}_base_level(const ${{self.c_ident}}& obj)
{ {
switch(obj) { switch(obj) {
''') ''')
@ -587,9 +634,10 @@ int ${{self.c_ident}}_base_level(const ${{self.c_ident}}& obj)
/** \\brief returns the machine type for each base vector index used by NetDest /** \\brief returns the machine type for each base vector index used by NetDest
* *
* \\return the MachineTYpe * \\return the MachineType
*/ */
MachineType ${{self.c_ident}}_from_base_level(int type) MachineType
${{self.c_ident}}_from_base_level(int type)
{ {
switch(type) { switch(type) {
''') ''')
@ -614,7 +662,8 @@ MachineType ${{self.c_ident}}_from_base_level(int type)
* *
* \\return the base number of components for each machine * \\return the base number of components for each machine
*/ */
int ${{self.c_ident}}_base_number(const ${{self.c_ident}}& obj) int
${{self.c_ident}}_base_number(const ${{self.c_ident}}& obj)
{ {
int base = 0; int base = 0;
switch(obj) { switch(obj) {
@ -641,7 +690,8 @@ int ${{self.c_ident}}_base_number(const ${{self.c_ident}}& obj)
/** \\brief returns the total number of components for each machine /** \\brief returns the total number of components for each machine
* \\return the total number of components for each machine * \\return the total number of components for each machine
*/ */
int ${{self.c_ident}}_base_count(const ${{self.c_ident}}& obj) int
${{self.c_ident}}_base_count(const ${{self.c_ident}}& obj)
{ {
switch(obj) { switch(obj) {
''') ''')