From efc41fe82d6e1acb82aadd1063efd5e223f876f7 Mon Sep 17 00:00:00 2001 From: Steve Reinhardt Date: Tue, 28 Mar 2006 22:29:42 -0500 Subject: [PATCH] Make .isa-file ##include file paths relative to including file. Makes .isa files cleaner and simplifies scanner too. Simplified scanner to work under both old and new versions of scons. arch/SConscript: Simplify .isa scanner... seems to work with both scons 0.96.1 and 0.96.91 now. Assumes .isa ##include paths are relative to including file. arch/alpha/isa/main.isa: arch/mips/isa/formats/formats.isa: arch/mips/isa/main.isa: arch/sparc/isa/formats.isa: arch/sparc/isa/main.isa: Make ##include paths relative to including file. arch/isa_parser.py: Make ##include file paths relative to including file. Makes .isa files cleaner and simplifies scanner too. Partial rewrite of include-handling code to use cool re.sub() feature where you can specify a function to provide the replacement string. Minor cleanup of error-handling code. Also got rid of '#!' at top to make caller choose which python interpreter is used (since SPARC now requires 2.4 to build, we may need to do that via scons in the future). --HG-- rename : arch/mips/isa/formats.isa => arch/mips/isa/formats/formats.isa extra : convert_revision : 15a3920fa3aaf80cd94083eda853aa4e49425045 --- arch/SConscript | 19 ++---- arch/alpha/isa/main.isa | 20 +++--- arch/isa_parser.py | 108 +++++++++++++++--------------- arch/mips/isa/formats.isa | 35 ---------- arch/mips/isa/formats/formats.isa | 35 ++++++++++ arch/mips/isa/main.isa | 12 ++-- arch/sparc/isa/formats.isa | 18 ++--- arch/sparc/isa/main.isa | 12 ++-- 8 files changed, 126 insertions(+), 133 deletions(-) delete mode 100644 arch/mips/isa/formats.isa create mode 100644 arch/mips/isa/formats/formats.isa diff --git a/arch/SConscript b/arch/SConscript index d88d10368..99c861568 100644 --- a/arch/SConscript +++ b/arch/SConscript @@ -100,18 +100,12 @@ for hdr in isa_switch_hdrs: # import SCons.Scanner -def ISAScan(): - return SCons.Scanner.Classic("ISAScan", - "$ISASUFFIXES", - "SRCDIR", - '^[ \t]*##[ \t]*include[ \t]*"([^>"]+)"') +isa_scanner = SCons.Scanner.Classic("ISAScan", + [".isa", ".ISA"], + "SRCDIR", + r'^\s*##include\s+"([\w/.-]*)"') -def ISAPath(env, dir, target=None, source=None, a=None): - return (Dir(env['SRCDIR']), Dir('.')) - -iscan = Scanner(function = ISAScan().scan, skeys = [".isa", ".ISA"], - path_function = ISAPath) -env.Append(SCANNERS = iscan) +env.Append(SCANNERS = isa_scanner) # # Now create a Builder object that uses isa_parser.py to generate C++ @@ -138,8 +132,7 @@ def isa_desc_emitter(target, source, env): return (isa_desc_gen_files, [isa_parser, cpu_models_file] + source) # Pieces are in place, so create the builder. -isa_desc_builder = Builder(action='$SOURCES $TARGET.dir $CPU_MODELS', - source_scanner = iscan, +isa_desc_builder = Builder(action='python $SOURCES $TARGET.dir $CPU_MODELS', emitter = isa_desc_emitter) env.Append(BUILDERS = { 'ISADesc' : isa_desc_builder }) diff --git a/arch/alpha/isa/main.isa b/arch/alpha/isa/main.isa index d4c744fbc..746fe776d 100644 --- a/arch/alpha/isa/main.isa +++ b/arch/alpha/isa/main.isa @@ -418,31 +418,31 @@ def format BasicOperateWithNopCheck(code, *opt_args) {{ }}; // Integer instruction templates, formats, etc. -##include "m5/arch/alpha/isa/int.isa" +##include "int.isa" // Floating-point instruction templates, formats, etc. -##include "m5/arch/alpha/isa/fp.isa" +##include "fp.isa" // Memory instruction templates, formats, etc. -##include "m5/arch/alpha/isa/mem.isa" +##include "mem.isa" // Branch/jump instruction templates, formats, etc. -##include "m5/arch/alpha/isa/branch.isa" +##include "branch.isa" // PAL instruction templates, formats, etc. -##include "m5/arch/alpha/isa/pal.isa" +##include "pal.isa" // Opcdec fault instruction templates, formats, etc. -##include "m5/arch/alpha/isa/opcdec.isa" +##include "opcdec.isa" // Unimplemented instruction templates, formats, etc. -##include "m5/arch/alpha/isa/unimp.isa" +##include "unimp.isa" // Unknown instruction templates, formats, etc. -##include "m5/arch/alpha/isa/unknown.isa" +##include "unknown.isa" // Execution utility functions -##include "m5/arch/alpha/isa/util.isa" +##include "util.isa" // The actual decoder -##include "m5/arch/alpha/isa/decoder.isa" +##include "decoder.isa" diff --git a/arch/isa_parser.py b/arch/isa_parser.py index 3f836ed7e..6fce783b1 100755 --- a/arch/isa_parser.py +++ b/arch/isa_parser.py @@ -1,5 +1,3 @@ -#! /usr/bin/env python - # Copyright (c) 2003-2005 The Regents of The University of Michigan # All rights reserved. # @@ -162,13 +160,12 @@ def t_CPPDIRECTIVE(t): def t_NEWFILE(t): r'^\#\#newfile\s+"[\w/.-]*"' - global fileNameStack - fileNameStack.append((t.value[11:-1], t.lineno)) + fileNameStack.push((t.value[11:-1], t.lineno)) t.lineno = 0 def t_ENDFILE(t): r'^\#\#endfile' - (filename, t.lineno) = fileNameStack.pop() + (old_filename, t.lineno) = fileNameStack.pop() # # The functions t_NEWLINE, t_ignore, and t_error are @@ -698,7 +695,7 @@ def p_error(t): if t: error(t.lineno, "syntax error at '%s'" % t.value) else: - error_bt(0, "unknown syntax error") + error(0, "unknown syntax error", True) # END OF GRAMMAR RULES # @@ -896,6 +893,12 @@ formatStack = Stack(NoFormat()) # The global default case stack. defaultStack = Stack( None ) +# Global stack that tracks current file and line number. +# Each element is a tuple (filename, lineno) that records the +# *current* filename and the line number in the *previous* file where +# it was included. +fileNameStack = Stack() + ################### # Utility functions @@ -932,25 +935,22 @@ def fixPythonIndentation(s): return s # Error handler. Just call exit. Output formatted to work under -# Emacs compile-mode. This function should be called when errors due -# to user input are detected (as opposed to parser bugs). -def error(lineno, string): +# Emacs compile-mode. Optional 'print_traceback' arg, if set to True, +# prints a Python stack backtrace too (can be handy when trying to +# debug the parser itself). +def error(lineno, string, print_traceback = False): spaces = "" for (filename, line) in fileNameStack[0:-1]: - print spaces + "In file included from " + filename + print spaces + "In file included from " + filename + ":" spaces += " " - # Uncomment the following line to get a Python stack backtrace for - # these errors too. Can be handy when trying to debug the parser. - # traceback.print_exc() - sys.exit(spaces + "%s:%d: %s" % (fileNameStack[-1][0], lineno, string)) - -# Like error(), but include a Python stack backtrace (for processing -# Python exceptions). This function should be called for errors that -# appear to be bugs in the parser itself. -def error_bt(lineno, string): - traceback.print_exc() - print >> sys.stderr, "%s:%d: %s" % (input_filename, lineno, string) - sys.exit(1) + # Print a Python stack backtrace if requested. + if (print_traceback): + traceback.print_exc() + if lineno != 0: + line_str = "%d:" % lineno + else: + line_str = "" + sys.exit(spaces + "%s:%s %s" % (fileNameStack[-1][0], line_str, string)) ##################################################################### @@ -1070,7 +1070,7 @@ def buildOperandTypeMap(userDict, lineno): elif size == 64: ctype = 'double' if ctype == '': - error(0, 'Unrecognized type description "%s" in userDict') + error(lineno, 'Unrecognized type description "%s" in userDict') operandTypeMap[ext] = (size, ctype, is_signed) # @@ -1701,47 +1701,47 @@ def update_if_needed(file, contents): f.write(contents) f.close() -# This regular expression matches include directives +# This regular expression matches '##include' directives includeRE = re.compile(r'^\s*##include\s+"(?P[\w/.-]*)".*$', re.MULTILINE) -def preprocess_isa_desc(isa_desc): +# Function to replace a matched '##include' directive with the +# contents of the specified file (with nested ##includes replaced +# recursively). 'matchobj' is an re match object (from a match of +# includeRE) and 'dirname' is the directory relative to which the file +# path should be resolved. +def replace_include(matchobj, dirname): + fname = matchobj.group('filename') + full_fname = os.path.normpath(os.path.join(dirname, fname)) + contents = '##newfile "%s"\n%s\n##endfile\n' % \ + (full_fname, read_and_flatten(full_fname)) + return contents + +# Read a file and recursively flatten nested '##include' files. +def read_and_flatten(filename): + current_dir = os.path.dirname(filename) + try: + contents = open(filename).read() + except IOError: + error(0, 'Error including file "%s"' % filename) + fileNameStack.push((filename, 0)) # Find any includes and include them - pos = 0 - while 1: - m = includeRE.search(isa_desc, pos) - if not m: - break - filename = m.group('filename') - print 'Including file "%s"' % filename - try: - isa_desc = isa_desc[:m.start()] + \ - '##newfile "' + filename + '"\n' + \ - open(filename).read() + \ - '##endfile\n' + \ - isa_desc[m.end():] - except IOError: - error(0, 'Error including file "%s"' % (filename)) - pos = m.start() - return isa_desc + contents = includeRE.sub(lambda m: replace_include(m, current_dir), + contents) + fileNameStack.pop() + return contents # # Read in and parse the ISA description. # def parse_isa_desc(isa_desc_file, output_dir): - # set a global var for the input filename... used in error messages - global input_filename - input_filename = isa_desc_file - global fileNameStack - fileNameStack = [(input_filename, 1)] + # Read file and (recursively) all included files into a string. + # PLY requires that the input be in a single string so we have to + # do this up front. + isa_desc = read_and_flatten(isa_desc_file) - # Suck the ISA description file in. - input = open(isa_desc_file) - isa_desc = input.read() - input.close() - - # Perform Preprocessing - isa_desc = preprocess_isa_desc(isa_desc) + # Initialize filename stack with outer file. + fileNameStack.push((isa_desc_file, 0)) # Parse it. (isa_name, namespace, global_code, namespace_code) = yacc.parse(isa_desc) diff --git a/arch/mips/isa/formats.isa b/arch/mips/isa/formats.isa deleted file mode 100644 index f7a9e4ce2..000000000 --- a/arch/mips/isa/formats.isa +++ /dev/null @@ -1,35 +0,0 @@ -// -*- mode:c++ -*- - -//Templates from this format are used later -//Include the basic format -##include "m5/arch/mips/isa/formats/basic.isa" - -//Include the basic format -##include "m5/arch/mips/isa/formats/noop.isa" - -//Include utility formats/functions -##include "m5/arch/mips/isa/formats/util.isa" - -//Include the cop0 formats -##include "m5/arch/mips/isa/formats/cop0.isa" - -//Include the integer formats -##include "m5/arch/mips/isa/formats/int.isa" - -//Include the floatOp format -##include "m5/arch/mips/isa/formats/fp.isa" - -//Include the mem format -##include "m5/arch/mips/isa/formats/mem.isa" - -//Include the trap format -##include "m5/arch/mips/isa/formats/trap.isa" - -//Include the branch format -##include "m5/arch/mips/isa/formats/branch.isa" - -//Include the noop format -##include "m5/arch/mips/isa/formats/unimp.isa" - -//Include the noop format -##include "m5/arch/mips/isa/formats/unknown.isa" diff --git a/arch/mips/isa/formats/formats.isa b/arch/mips/isa/formats/formats.isa new file mode 100644 index 000000000..7d493ffae --- /dev/null +++ b/arch/mips/isa/formats/formats.isa @@ -0,0 +1,35 @@ +// -*- mode:c++ -*- + +//Templates from this format are used later +//Include the basic format +##include "basic.isa" + +//Include the basic format +##include "noop.isa" + +//Include utility functions +##include "util.isa" + +//Include the cop0 formats +##include "cop0.isa" + +//Include the integer formats +##include "int.isa" + +//Include the floatOp format +##include "fp.isa" + +//Include the mem format +##include "mem.isa" + +//Include the trap format +##include "trap.isa" + +//Include the branch format +##include "branch.isa" + +//Include the noop format +##include "unimp.isa" + +//Include the noop format +##include "unknown.isa" diff --git a/arch/mips/isa/main.isa b/arch/mips/isa/main.isa index 411e398b4..01d81323e 100644 --- a/arch/mips/isa/main.isa +++ b/arch/mips/isa/main.isa @@ -26,7 +26,7 @@ // (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 "m5/arch/mips/isa/includes.isa" +##include "includes.isa" //////////////////////////////////////////////////////////////////// // @@ -37,16 +37,16 @@ namespace MipsISA; //Include the bitfield definitions -##include "m5/arch/mips/isa/bitfields.isa" +##include "bitfields.isa" //Include the operand_types and operand definitions -##include "m5/arch/mips/isa/operands.isa" +##include "operands.isa" //Include the base class for mips instructions, and some support code -##include "m5/arch/mips/isa/base.isa" +##include "base.isa" //Include the definitions for the instruction formats -##include "m5/arch/mips/isa/formats.isa" +##include "formats/formats.isa" //Include the decoder definition -##include "m5/arch/mips/isa/decoder.isa" +##include "decoder.isa" diff --git a/arch/sparc/isa/formats.isa b/arch/sparc/isa/formats.isa index 9310ba3d3..8683f5e01 100644 --- a/arch/sparc/isa/formats.isa +++ b/arch/sparc/isa/formats.isa @@ -1,28 +1,28 @@ //Include the basic format //Templates from this format are used later -##include "m5/arch/sparc/isa/formats/basic.isa" +##include "formats/basic.isa" //Include the integerOp and integerOpCc format -##include "m5/arch/sparc/isa/formats/integerop.isa" +##include "formats/integerop.isa" //Include the memory format -##include "m5/arch/sparc/isa/formats/mem.isa" +##include "formats/mem.isa" //Include the compare and swap format -##include "m5/arch/sparc/isa/formats/cas.isa" +##include "formats/cas.isa" //Include the trap format -##include "m5/arch/sparc/isa/formats/trap.isa" +##include "formats/trap.isa" //Include the "unknown" format -##include "m5/arch/sparc/isa/formats/unknown.isa" +##include "formats/unknown.isa" //Include the priveleged mode format -##include "m5/arch/sparc/isa/formats/priv.isa" +##include "formats/priv.isa" //Include the branch format -##include "m5/arch/sparc/isa/formats/branch.isa" +##include "formats/branch.isa" //Include the noop format -##include "m5/arch/sparc/isa/formats/noop.isa" +##include "formats/noop.isa" diff --git a/arch/sparc/isa/main.isa b/arch/sparc/isa/main.isa index ab0290d58..35167d6b7 100644 --- a/arch/sparc/isa/main.isa +++ b/arch/sparc/isa/main.isa @@ -26,7 +26,7 @@ // (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 "m5/arch/sparc/isa/includes.isa" +##include "includes.isa" //////////////////////////////////////////////////////////////////// // @@ -37,16 +37,16 @@ namespace SparcISA; //Include the bitfield definitions -##include "m5/arch/sparc/isa/bitfields.isa" +##include "bitfields.isa" //Include the operand_types and operand definitions -##include "m5/arch/sparc/isa/operands.isa" +##include "operands.isa" //Include the base class for sparc instructions, and some support code -##include "m5/arch/sparc/isa/base.isa" +##include "base.isa" //Include the definitions for the instruction formats -##include "m5/arch/sparc/isa/formats.isa" +##include "formats.isa" //Include the decoder definition -##include "m5/arch/sparc/isa/decoder.isa" +##include "decoder.isa"