Chromium Code Reviews| 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): |
|
Karl
2011/09/19 19:56:05
NIT: Again, thumb2 or thumb?
jasonwkim
2011/09/26 21:35:52
in this case, I am going to punt and not fix - the
|
| """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): |