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): |