Ruby: Modify Scons so that we can put .sm files in extras
authorJason Power <power.jg@gmail.com>
Wed, 12 Sep 2012 19:52:04 +0000 (14:52 -0500)
committerJason Power <power.jg@gmail.com>
Wed, 12 Sep 2012 19:52:04 +0000 (14:52 -0500)
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
src/mem/protocol/SConscript
src/mem/protocol/SConsopts
src/mem/slicc/parser.py
src/mem/slicc/symbols/Func.py
src/mem/slicc/symbols/StateMachine.py
src/mem/slicc/symbols/SymbolTable.py
src/mem/slicc/symbols/Type.py
src/mem/slicc/symbols/Var.py

index c832fa1b86fd3fea3c4944aea0c6360dedb54aad..34b333f603d0a452f635a64f421266e0538afdc5 100755 (executable)
@@ -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 <fenv.h> 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',
+               ]
 
 ###################################################
 #
index 9ef38d289a5933d68150069225ff1d26c1e1101f..0eccdf3e51ab3a41a08ca3c524b9b2bb944671f6 100644 (file)
@@ -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})
index 78b93c40e1de5a9f20b90ec0db4bf18b37186f29..95b043bc5d5c735b8eca25677d2f818bc9172fa6 100644 (file)
@@ -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')
index e4f3ba9529feec6290cb178cb867938a8ee63cd6..77ac4de56d131a26ef7739d46abb2911d6033f0d 100644 (file)
@@ -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):
index 771144efd8e965dd08d5f800aab371fb6bf91535..ebbc5fe14134cc5361433fb1a3b122c220cfe4ef 100644 (file)
@@ -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):
index 83ad88e8b9422ce4a58a91576967a47fa6b9e497..47f7daa00abbb47ccfd969d6de3f914270ca9d68 100644 (file)
@@ -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;
 
index 81d0768f92ad2ae93af51f3c41437de6cfb3710e..d2c9337f1b7328921e73d9d09f540497d69b1d46 100644 (file)
@@ -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)
index 3285b767f5e9d486ced48b295731d8d528722465..aec05a67874402540093ce5f0d7f8c7be7bdb215 100644 (file)
@@ -184,7 +184,7 @@ class Type(Symbol):
 
         return True
 
-    def writeCodeFiles(self, path):
+    def writeCodeFiles(self, path, includes):
         if self.isExternal:
             # Do nothing
             pass
index 87a101f65da91875ba242dd08a2f088e16f5fa7f..e16199a1e97b81c9fd0676c0eb811541790e6a92 100644 (file)
@@ -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" ]