| Index: src/trusted/validator_arm/dgen_output.py
|
| diff --git a/src/trusted/validator_arm/dgen_output.py b/src/trusted/validator_arm/dgen_output.py
|
| index 7c0924b902862756ea714c2810e61b0aa6094438..edf811f303e0d8091c86df0b8d7889d088d7af22 100644
|
| --- a/src/trusted/validator_arm/dgen_output.py
|
| +++ b/src/trusted/validator_arm/dgen_output.py
|
| @@ -1,9 +1,9 @@
|
| #!/usr/bin/python
|
| #
|
| -# Copyright 2009 The Native Client Authors. All rights reserved.
|
| +# Copyright (c) 2011 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 2009, Google Inc.
|
| +# Copyright (c) 2011, Google Inc.
|
| #
|
|
|
| """
|
| @@ -12,28 +12,33 @@ Responsible for generating the decoder based on parsed table representations.
|
|
|
| import dgen_opt
|
|
|
| -def generate_decoder(tables, out):
|
| +def generate_decoder(arm_tables, thumb_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.')
|
| + if len(arm_tables + thumb_tables) == 0:
|
| + raise Exception('No tables provided.')
|
|
|
| _generate_header(out)
|
| out.line()
|
| out.line('namespace nacl_arm_dec {')
|
| out.line()
|
| - _generate_decoder_state_type(tables, out)
|
| + _generate_decoder_state_type(arm_tables + thumb_tables, out)
|
| out.line()
|
| - _generate_prototypes(tables, out)
|
| + _generate_prototypes("arm", arm_tables, out)
|
| out.line()
|
| - _generate_implementations(tables, out)
|
| + _generate_prototypes("thumb", thumb_tables, out)
|
| + out.line()
|
| + _generate_implementations("arm", arm_tables, out)
|
| + out.line()
|
| + _generate_implementations("thumb", thumb_tables, out)
|
| out.line()
|
| _generate_init_function(out)
|
| out.line()
|
| - _generate_entry_point(tables[0].name, out)
|
| + _generate_entry_point(arm_tables[0].name, thumb_tables[0].name, out)
|
| out.line()
|
| out.line('} // namespace')
|
|
|
| @@ -58,65 +63,73 @@ def _generate_decoder_state_type(tables, out):
|
| terminals.add(r.action[1:])
|
|
|
| out.enter_block('struct DecoderState')
|
| -
|
| + # We need to track our thumb state
|
| + out.line('const uint8_t thumb;')
|
| for t in terminals:
|
| out.line('const %s _%s_instance;' % (t, t))
|
|
|
| - out.line('DecoderState() :')
|
| - first = True
|
| + out.line('DecoderState(uint8_t thumb) :')
|
| + # Pass through thumb initialization
|
| + out.line('thumb(thumb)')
|
| for t in terminals:
|
| - if first:
|
| - out.line('_%s_instance()' % t)
|
| - else:
|
| - out.line(',_%s_instance()' % t)
|
| - first = False
|
| + out.line(',_%s_instance()' % t)
|
| out.line('{}')
|
|
|
| out.exit_block(';')
|
|
|
|
|
| -def _generate_prototypes(tables, out):
|
| +def _generate_prototypes(name, 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)
|
| + out.line('static inline const ClassDecoder &%s_decode_%s('
|
| + 'const Instruction insn, const DecoderState *state);' %
|
| + (name, t.name))
|
|
|
| -def _generate_implementations(tables, out):
|
| +def _generate_implementations(name, tables, out):
|
| out.block_comment('Table-matching function implementations.')
|
| for t in tables:
|
| out.line()
|
| - _generate_table(t, out)
|
| + _generate_table(name, t, out)
|
|
|
|
|
| def _generate_init_function(out):
|
| - out.enter_block('const DecoderState *init_decode()')
|
| - out.line('return new DecoderState;')
|
| + out.enter_block('const DecoderState *init_decode(uint8_t thumb)')
|
| + out.line('return new DecoderState(thumb);')
|
| 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):
|
| +def _generate_entry_point(arm_table_name, thumb_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.enter_block('if (state->thumb)')
|
| + out.line('return thumb_decode_%s(insn, (DecoderState *)state);'
|
| + % thumb_table_name)
|
| + out.exit_block()
|
| + out.enter_block('else')
|
| + out.line('return arm_decode_%s(insn, (DecoderState *)state);'
|
| + % arm_table_name)
|
| + out.exit_block()
|
| out.exit_block()
|
|
|
|
|
| -def _generate_table(table, out):
|
| +def _generate_table(name, 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)
|
| + out.enter_block('static inline const ClassDecoder &%s_decode_%s('
|
| + 'const Instruction insn, const DecoderState *state)' %
|
| + (name, table.name))
|
|
|
| optimized = dgen_opt.optimize_rows(table.rows)
|
| print ("Table %s: %d rows minimized to %d"
|
| % (table.name, len(table.rows), len(optimized)))
|
| + #out.line("printf(\"mrm DEBUG: Flowing through table " + table.name +
|
| + # " decoding %x\\n\", insn.bits(31, 0));")
|
| for row in sorted(optimized):
|
| exprs = ["(%s)" % p.to_c_expr('insn') for p in row.patterns]
|
| out.enter_block('if (%s)' % ' && '.join(exprs))
|
| @@ -124,7 +137,7 @@ def _generate_table(table, out):
|
| if row.action.startswith('='):
|
| _generate_terminal(row.action[1:], out)
|
| elif row.action.startswith('->'):
|
| - _generate_table_change(row.action[2:], out)
|
| + _generate_table_change(name, row.action[2:], out)
|
| else:
|
| raise Exception('Bad table action: %s' % row.action)
|
|
|
| @@ -139,8 +152,8 @@ 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_table_change(mode, name, out):
|
| + out.line('return %s_decode_%s(insn, state);' % (mode, name))
|
|
|
|
|
| def _generate_safety_net(table, out):
|
|
|