From aa8bcd15ec1ba916f3e750f41697a65e06b3c2ac Mon Sep 17 00:00:00 2001 From: Jason Power Date: Wed, 12 Sep 2012 14:52:04 -0500 Subject: [PATCH] Ruby: Modify Scons so that we can put .sm files in extras Also allows for header files which are required in slicc generated code to be in a directory other than src/mem/ruby/slicc_interface. --- SConstruct | 15 +++++++++++++-- src/mem/protocol/SConscript | 23 ++++++++++++++++------- src/mem/protocol/SConsopts | 17 +++++++++-------- src/mem/slicc/parser.py | 12 ++++++++---- src/mem/slicc/symbols/Func.py | 2 +- src/mem/slicc/symbols/StateMachine.py | 24 +++++++++++++++++------- src/mem/slicc/symbols/SymbolTable.py | 12 ++++++------ src/mem/slicc/symbols/Type.py | 2 +- src/mem/slicc/symbols/Var.py | 2 +- 9 files changed, 72 insertions(+), 37 deletions(-) diff --git a/SConstruct b/SConstruct index c832fa1b8..34b333f60 100755 --- a/SConstruct +++ b/SConstruct @@ -116,7 +116,7 @@ extra_python_paths = [ Dir('src/python').srcnode().abspath, # gem5 includes Dir('ext/ply').srcnode().abspath, # ply is used by several files ] - + sys.path[1:1] = extra_python_paths from m5.util import compareVersions, readCommand @@ -835,6 +835,14 @@ Export('sticky_vars') export_vars = [] Export('export_vars') +# For Ruby +all_protocols = [] +Export('all_protocols') +protocol_dirs = [] +Export('protocol_dirs') +slicc_includes = [] +Export('slicc_includes') + # Walk the tree and execute all SConsopts scripts that wil add to the # above variables if not GetOption('verbose'): @@ -867,11 +875,14 @@ sticky_vars.AddVariables( BoolVariable('USE_POSIX_CLOCK', 'Use POSIX Clocks', have_posix_clock), BoolVariable('USE_FENV', 'Use IEEE mode control', have_fenv), BoolVariable('CP_ANNOTATE', 'Enable critical path annotation capability', False), + EnumVariable('PROTOCOL', 'Coherence protocol for Ruby', 'None', + all_protocols), ) # These variables get exported to #defines in config/*.hh (see src/SConscript). export_vars += ['USE_FENV', 'SS_COMPATIBLE_FP', - 'TARGET_ISA', 'CP_ANNOTATE', 'USE_POSIX_CLOCK' ] + 'TARGET_ISA', 'CP_ANNOTATE', 'USE_POSIX_CLOCK', 'PROTOCOL', + ] ################################################### # diff --git a/src/mem/protocol/SConscript b/src/mem/protocol/SConscript index 9ef38d289..0eccdf3e5 100644 --- a/src/mem/protocol/SConscript +++ b/src/mem/protocol/SConscript @@ -41,7 +41,7 @@ Import('*') if env['PROTOCOL'] == 'None': Return() -protocol_dir = Dir('.') +output_dir = Dir('.') html_dir = Dir('html') slicc_dir = Dir('../slicc') @@ -57,7 +57,7 @@ for root,dirs,files in os.walk(slicc_dir.srcnode().abspath): # # Use SLICC # -env['SLICC_PATH'] = str(protocol_dir) +env["SLICC_PATH"] = protocol_dirs slicc_scanner = Classic("SliccScanner", ['.sm', '.slicc'], "SLICC_PATH", r'''include[ \t]["'](.*)["'];''') env.Append(SCANNERS=slicc_scanner) @@ -66,22 +66,22 @@ def slicc_emitter(target, source, env): assert len(source) == 1 filepath = source[0].srcnode().abspath - slicc = SLICC(filepath, verbose=False) + slicc = SLICC(filepath, protocol_base.abspath, verbose=False) slicc.process() - slicc.writeCodeFiles(protocol_dir.abspath) + slicc.writeCodeFiles(output_dir.abspath, slicc_includes) if env['SLICC_HTML']: slicc.writeHTMLFiles(html_dir.abspath) - target.extend([protocol_dir.File(f) for f in sorted(slicc.files())]) + target.extend([output_dir.File(f) for f in sorted(slicc.files())]) return target, source def slicc_action(target, source, env): assert len(source) == 1 filepath = source[0].srcnode().abspath - slicc = SLICC(filepath, verbose=True) + slicc = SLICC(filepath, protocol_base.abspath, verbose=True) slicc.process() - slicc.writeCodeFiles(protocol_dir.abspath) + slicc.writeCodeFiles(output_dir.abspath, slicc_includes) if env['SLICC_HTML']: slicc.writeHTMLFiles(html_dir.abspath) @@ -89,6 +89,15 @@ slicc_builder = Builder(action=MakeAction(slicc_action, Transform("SLICC")), emitter=slicc_emitter) protocol = env['PROTOCOL'] +protocol_dir = None +for path in protocol_dirs: + if os.path.exists(os.path.join(path, "%s.slicc" % protocol)): + protocol_dir = Dir(path) + break + +if not protocol_dir: + raise ValueError, "Could not find %s.slicc in protocol_dirs" % protocol + sources = [ protocol_dir.File("%s.slicc" % protocol) ] env.Append(BUILDERS={'SLICC' : slicc_builder}) diff --git a/src/mem/protocol/SConsopts b/src/mem/protocol/SConsopts index 78b93c40e..95b043bc5 100644 --- a/src/mem/protocol/SConsopts +++ b/src/mem/protocol/SConsopts @@ -32,7 +32,7 @@ import os Import('*') -all_protocols = [ +all_protocols.extend([ 'MESI_CMP_directory', 'MI_example', 'MOESI_CMP_directory', @@ -40,13 +40,14 @@ all_protocols = [ 'MOESI_hammer', 'Network_test', 'None' - ] - -opt = EnumVariable('PROTOCOL', 'Coherence protocol for Ruby', 'None', - all_protocols) - -sticky_vars.AddVariables(opt) -export_vars += ['PROTOCOL'] + ]) opt = BoolVariable('SLICC_HTML', 'Create HTML files', False) sticky_vars.AddVariables(opt) + +protocol_dirs.append(Dir('.').abspath) + +protocol_base = Dir('.') +Export('protocol_base') + +slicc_includes.append('mem/ruby/slicc_interface/RubySlicc_includes.hh') diff --git a/src/mem/slicc/parser.py b/src/mem/slicc/parser.py index e4f3ba952..77ac4de56 100644 --- a/src/mem/slicc/parser.py +++ b/src/mem/slicc/parser.py @@ -38,11 +38,12 @@ import slicc.util as util from slicc.symbols import SymbolTable class SLICC(Grammar): - def __init__(self, filename, verbose=False, traceback=False, **kwargs): + def __init__(self, filename, base_dir, verbose=False, traceback=False, **kwargs): self.protocol = None self.traceback = traceback self.verbose = verbose self.symtab = SymbolTable(self) + self.base_dir = base_dir try: self.decl_list = self.parse_file(filename, **kwargs) @@ -64,8 +65,8 @@ class SLICC(Grammar): self.decl_list.findMachines() self.decl_list.generate() - def writeCodeFiles(self, code_path): - self.symtab.writeCodeFiles(code_path) + def writeCodeFiles(self, code_path, includes): + self.symtab.writeCodeFiles(code_path, includes) def writeHTMLFiles(self, html_path): self.symtab.writeHTMLFiles(html_path) @@ -249,7 +250,10 @@ class SLICC(Grammar): def p_decl__include(self, p): "decl : INCLUDE STRING SEMI" dirname = os.path.dirname(self.current_source) - filename = os.path.join(dirname, p[2]) + if os.path.exists(os.path.join(dirname, p[2])): + filename = os.path.join(dirname, p[2]) + else: + filename = os.path.join(self.base_dir, p[2]) p[0] = self.parse_file(filename) def p_decl__machine(self, p): diff --git a/src/mem/slicc/symbols/Func.py b/src/mem/slicc/symbols/Func.py index 771144efd..ebbc5fe14 100644 --- a/src/mem/slicc/symbols/Func.py +++ b/src/mem/slicc/symbols/Func.py @@ -63,7 +63,7 @@ class Func(Symbol): return "%s %s(%s);" % (return_type, self.c_ident, ", ".join(self.param_strings)) - def writeCodeFiles(self, path): + def writeCodeFiles(self, path, includes): return def generateCode(self): diff --git a/src/mem/slicc/symbols/StateMachine.py b/src/mem/slicc/symbols/StateMachine.py index 83ad88e8b..47f7daa00 100644 --- a/src/mem/slicc/symbols/StateMachine.py +++ b/src/mem/slicc/symbols/StateMachine.py @@ -162,12 +162,12 @@ class StateMachine(Symbol): action.warning(error_msg) self.table = table - def writeCodeFiles(self, path): + def writeCodeFiles(self, path, includes): self.printControllerPython(path) self.printControllerHH(path) - self.printControllerCC(path) + self.printControllerCC(path, includes) self.printCSwitch(path) - self.printCWakeup(path) + self.printCWakeup(path, includes) self.printProfilerCC(path) self.printProfilerHH(path) self.printProfileDumperCC(path) @@ -399,7 +399,7 @@ void unset_tbe(${{self.TBEType.c_ident}}*& m_tbe_ptr); code('#endif // __${ident}_CONTROLLER_H__') code.write(path, '%s.hh' % c_ident) - def printControllerCC(self, path): + def printControllerCC(self, path, includes): '''Output the actions for performing the actions''' code = self.symtab.codeFormatter() @@ -429,8 +429,12 @@ void unset_tbe(${{self.TBEType.c_ident}}*& m_tbe_ptr); #include "mem/protocol/${ident}_State.hh" #include "mem/protocol/Types.hh" #include "mem/ruby/common/Global.hh" -#include "mem/ruby/slicc_interface/RubySlicc_includes.hh" #include "mem/ruby/system/System.hh" +''') + for include_path in includes: + code('#include "${{include_path}}"') + + code(''' using namespace std; ''') @@ -988,7 +992,7 @@ $c_ident::${{action.ident}}(const Address& addr) code.write(path, "%s.cc" % c_ident) - def printCWakeup(self, path): + def printCWakeup(self, path, includes): '''Output the wakeup loop for the events''' code = self.symtab.codeFormatter() @@ -1020,8 +1024,14 @@ $c_ident::${{action.ident}}(const Address& addr) code(''' #include "mem/protocol/Types.hh" #include "mem/ruby/common/Global.hh" -#include "mem/ruby/slicc_interface/RubySlicc_includes.hh" #include "mem/ruby/system/System.hh" +''') + + + for include_path in includes: + code('#include "${{include_path}}"') + + code(''' using namespace std; diff --git a/src/mem/slicc/symbols/SymbolTable.py b/src/mem/slicc/symbols/SymbolTable.py index 81d0768f9..d2c9337f1 100644 --- a/src/mem/slicc/symbols/SymbolTable.py +++ b/src/mem/slicc/symbols/SymbolTable.py @@ -124,15 +124,15 @@ class SymbolTable(object): if isinstance(symbol, type): yield symbol - def writeCodeFiles(self, path): + def writeCodeFiles(self, path, includes): makeDir(path) code = self.codeFormatter() - code(''' -/** Auto generated C++ code started by $__file__:$__line__ */ + code('/** Auto generated C++ code started by $__file__:$__line__ */') + + for include_path in includes: + code('#include "${{include_path}}"') -#include "mem/ruby/slicc_interface/RubySlicc_includes.hh" -''') for symbol in self.sym_vec: if isinstance(symbol, Type) and not symbol.isPrimitive: code('#include "mem/protocol/${{symbol.c_ident}}.hh"') @@ -140,7 +140,7 @@ class SymbolTable(object): code.write(path, "Types.hh") for symbol in self.sym_vec: - symbol.writeCodeFiles(path) + symbol.writeCodeFiles(path, includes) def writeHTMLFiles(self, path): makeDir(path) diff --git a/src/mem/slicc/symbols/Type.py b/src/mem/slicc/symbols/Type.py index 3285b767f..aec05a678 100644 --- a/src/mem/slicc/symbols/Type.py +++ b/src/mem/slicc/symbols/Type.py @@ -184,7 +184,7 @@ class Type(Symbol): return True - def writeCodeFiles(self, path): + def writeCodeFiles(self, path, includes): if self.isExternal: # Do nothing pass diff --git a/src/mem/slicc/symbols/Var.py b/src/mem/slicc/symbols/Var.py index 87a101f65..e16199a1e 100644 --- a/src/mem/slicc/symbols/Var.py +++ b/src/mem/slicc/symbols/Var.py @@ -44,7 +44,7 @@ class Var(Symbol): def __repr__(self): return "[Var id: %s]" % (self.c_ident) - def writeCodeFiles(self, path): + def writeCodeFiles(self, path, includes): pass __all__ = [ "Var" ]