Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(339)

Unified Diff: src/trusted/validator_mips/dgen/dgen_output.py

Issue 9979025: [MIPS] Adding validator for MIPS architecture. (Closed) Base URL: http://src.chromium.org/native_client/trunk/src/native_client/
Patch Set: Rebased patch, conflict resolved. Created 8 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/trusted/validator_mips/dgen/dgen_opt.py ('k') | src/trusted/validator_mips/dgen/generate_decoder.py » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/trusted/validator_mips/dgen/dgen_output.py
diff --git a/src/trusted/validator_mips/dgen/dgen_output.py b/src/trusted/validator_mips/dgen/dgen_output.py
new file mode 100755
index 0000000000000000000000000000000000000000..47f40afb3f320909bf3038d022fa42f1b4e99fd7
--- /dev/null
+++ b/src/trusted/validator_mips/dgen/dgen_output.py
@@ -0,0 +1,188 @@
+#!/usr/bin/python
+#
+# Copyright 2012 The Native Client Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can
+# be found in the LICENSE file.
+# Copyright 2012, Google Inc.
+#
+
+"""
+Responsible for generating the decoder based on parsed table representations.
+"""
+
+import dgen_opt
+
+def generate_decoder(tables, out):
+ """Entry point to the decoder.
+
+ Args:
+ tables: list of Table objects to process.
+ out: a COutput object to write to.
+ """
+ if len(tables) == 0: raise Exception('No tables provided.')
+
+ _generate_header(out)
+ out.line()
+ out.line('namespace nacl_mips_dec {')
+ out.line()
+ _generate_decoder_state_type(tables, out)
+ out.line()
+ _generate_prototypes(tables, out)
+ out.line()
+ _generate_implementations(tables, out)
+ out.line()
+ _generate_init_function(out)
+ out.line()
+ _generate_entry_point(tables[0].name, out)
+ out.line()
+ out.line('} // namespace')
+
+def _generate_header(out):
+ # TODO do we need a big ridiculous license banner in generated code?
+ out.block_comment('DO NOT EDIT: GENERATED CODE')
+ out.line('#include <stdio.h>')
+ out.line('#include "native_client/src/trusted/validator_mips/decode.h"')
+
+
+def _generate_decoder_state_type(tables, out):
+ out.block_comment(
+ 'This beast holds a bunch of pre-created ClassDecoder instances, which',
+ 'we create in init_decode(). Because ClassDecoders are stateless, we',
+ 'can freely reuse them -- even across threads -- and avoid allocating',
+ 'in the inner decoder loop.'
+ )
+ terminals = set()
+ for t in tables:
+ for r in t.rows:
+ if r.action.startswith('='):
+ terminals.add(r.action[1:])
+
+ out.enter_block('struct DecoderState')
+
+ for t in terminals:
+ out.line('const %s _%s_instance;' % (t, t))
+
+ out.line('DecoderState() :')
+ first = True
+ for t in terminals:
+ if first:
+ out.line('_%s_instance()' % t)
+ else:
+ out.line(',_%s_instance()' % t)
+ first = False
+ out.line('{}')
+
+ out.exit_block(';')
+
+
+def _generate_prototypes(tables, out):
+ out.block_comment('Prototypes for static table-matching functions.')
+ for t in tables:
+ out.line('static inline const ClassDecoder &decode_%s('
+ 'const Instruction insn, const DecoderState *state);' % t.name)
+
+def _generate_implementations(tables, out):
+ out.block_comment('Table-matching function implementations.')
+ for t in tables:
+ out.line()
+ _generate_table(t, out)
+
+
+def _generate_init_function(out):
+ out.enter_block('const DecoderState *init_decode()')
+ out.line('return new DecoderState;')
+ out.exit_block()
+
+ out.enter_block('void delete_state(const DecoderState *state)')
+ out.line('delete (DecoderState *)state;')
+ out.exit_block()
+
+def _generate_entry_point(initial_table_name, out):
+ out.enter_block('const ClassDecoder &decode(const Instruction insn, '
+ 'const DecoderState *state)')
+ out.line('return decode_%s(insn, (DecoderState *)state);'
+ % initial_table_name)
+ out.exit_block()
+
+
+def _generate_table(table, out):
+ """Generates the implementation of a single table."""
+ out.block_comment(
+ 'Implementation of table %s.' % table.name,
+ 'Specified by: %s.' % table.citation
+ )
+ out.enter_block('static inline const ClassDecoder &decode_%s('
+ 'const Instruction insn, const DecoderState *state)' % table.name)
+
+ optimized = dgen_opt.optimize_rows(table.rows)
+ print ("Table %s: %d rows minimized to %d"
+ % (table.name, len(table.rows), len(optimized)))
+ for row in sorted(optimized):
+ exprs = ["(%s)" % p.to_c_expr('insn') for p in row.patterns]
+ out.enter_block('if (%s)' % ' && '.join(exprs))
+
+ if row.action.startswith('='):
+ _generate_terminal(row.action[1:], out)
+ elif row.action.startswith('->'):
+ _generate_table_change(row.action[2:], out)
+ else:
+ raise Exception('Bad table action: %s' % row.action)
+
+ out.exit_block()
+ out.line()
+
+ _generate_safety_net(table, out)
+ out.exit_block()
+
+
+def _generate_terminal(name, out):
+ out.line('return state->_%s_instance;' % name)
+
+
+def _generate_table_change(name, out):
+ out.line('return decode_%s(insn, state);' % name)
+
+
+def _generate_safety_net(table, out):
+ out.line('// Catch any attempt to fall through...')
+ out.line('fprintf(stderr, "TABLE IS INCOMPLETE: %s could not parse %%08X",'
+ 'insn.Bits(31,0));' % table.name)
+ _generate_terminal('Forbidden', out)
+
+
+class COutput(object):
+ """Provides nicely-formatted C++ output."""
+
+ def __init__(self, out):
+ self._out = out
+ self._indent = 0
+
+ def line(self, str = ''):
+ self._out.write(self._tabs())
+ self._out.write(str + '\n')
+
+ def enter_block(self, headline):
+ self.line(headline + ' {')
+ self._indent += 1
+
+ def exit_block(self, footer = ''):
+ self._indent -= 1
+ self.line('}' + footer)
+
+ def block_comment(self, *lines):
+ self.line('/*')
+ for s in lines:
+ self.line(' * ' + s)
+ self.line(' */')
+
+ def _tabs(self):
+ return ' ' * self._indent
+
+
+def each_index_pair(sequence):
+ """Utility method: Generates each unique index pair in sequence."""
+ for i in range(0, len(sequence)):
+ for j in range(i + 1, len(sequence)):
+ yield (i, j)
+
+
« no previous file with comments | « src/trusted/validator_mips/dgen/dgen_opt.py ('k') | src/trusted/validator_mips/dgen/generate_decoder.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698