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

Side by Side Diff: src/trusted/validator_arm/dgen_output.py

Issue 7799013: Intial Thumb2 Sandbox (naclrev 6680) Base URL: svn://svn.chromium.org/native_client/trunk/src/native_client
Patch Set: fix comma Created 9 years, 3 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 unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 #!/usr/bin/python 1 #!/usr/bin/python
2 # 2 #
3 # Copyright 2009 The Native Client Authors. All rights reserved. 3 # Copyright (c) 2011 The Native Client Authors. All rights reserved.
4 # Use of this source code is governed by a BSD-style license that can 4 # Use of this source code is governed by a BSD-style license that can
5 # be found in the LICENSE file. 5 # be found in the LICENSE file.
6 # Copyright 2009, Google Inc. 6 # Copyright (c) 2011, Google Inc.
7 # 7 #
8 8
9 """ 9 """
10 Responsible for generating the decoder based on parsed table representations. 10 Responsible for generating the decoder based on parsed table representations.
11 """ 11 """
12 12
13 import dgen_opt 13 import dgen_opt
14 14
15 def generate_decoder(tables, out): 15 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
16 """Entry point to the decoder. 16 """Entry point to the decoder.
17 17
18 Args: 18 Args:
19 tables: list of Table objects to process. 19 tables: list of Table objects to process.
20 out: a COutput object to write to. 20 out: a COutput object to write to.
21 """ 21 """
22 if len(tables) == 0: raise Exception('No tables provided.') 22 if len(arm_tables + thumb_tables) == 0:
23 raise Exception('No tables provided.')
23 24
24 _generate_header(out) 25 _generate_header(out)
25 out.line() 26 out.line()
26 out.line('namespace nacl_arm_dec {') 27 out.line('namespace nacl_arm_dec {')
27 out.line() 28 out.line()
28 _generate_decoder_state_type(tables, out) 29 _generate_decoder_state_type(arm_tables + thumb_tables, out)
29 out.line() 30 out.line()
30 _generate_prototypes(tables, out) 31 _generate_prototypes("arm", arm_tables, out)
31 out.line() 32 out.line()
32 _generate_implementations(tables, out) 33 _generate_prototypes("thumb", thumb_tables, out)
34 out.line()
35 _generate_implementations("arm", arm_tables, out)
36 out.line()
37 _generate_implementations("thumb", thumb_tables, out)
33 out.line() 38 out.line()
34 _generate_init_function(out) 39 _generate_init_function(out)
35 out.line() 40 out.line()
36 _generate_entry_point(tables[0].name, out) 41 _generate_entry_point(arm_tables[0].name, thumb_tables[0].name, out)
37 out.line() 42 out.line()
38 out.line('} // namespace') 43 out.line('} // namespace')
39 44
40 def _generate_header(out): 45 def _generate_header(out):
41 # TODO do we need a big ridiculous license banner in generated code? 46 # TODO do we need a big ridiculous license banner in generated code?
42 out.block_comment('DO NOT EDIT: GENERATED CODE') 47 out.block_comment('DO NOT EDIT: GENERATED CODE')
43 out.line('#include <stdio.h>') 48 out.line('#include <stdio.h>')
44 out.line('#include "native_client/src/trusted/validator_arm/decode.h"') 49 out.line('#include "native_client/src/trusted/validator_arm/decode.h"')
45 50
46 51
47 def _generate_decoder_state_type(tables, out): 52 def _generate_decoder_state_type(tables, out):
48 out.block_comment( 53 out.block_comment(
49 'This beast holds a bunch of pre-created ClassDecoder instances, which', 54 'This beast holds a bunch of pre-created ClassDecoder instances, which',
50 'we create in init_decode(). Because ClassDecoders are stateless, we', 55 'we create in init_decode(). Because ClassDecoders are stateless, we',
51 'can freely reuse them -- even across threads -- and avoid allocating', 56 'can freely reuse them -- even across threads -- and avoid allocating',
52 'in the inner decoder loop.' 57 'in the inner decoder loop.'
53 ) 58 )
54 terminals = set() 59 terminals = set()
55 for t in tables: 60 for t in tables:
56 for r in t.rows: 61 for r in t.rows:
57 if r.action.startswith('='): 62 if r.action.startswith('='):
58 terminals.add(r.action[1:]) 63 terminals.add(r.action[1:])
59 64
60 out.enter_block('struct DecoderState') 65 out.enter_block('struct DecoderState')
61 66 # We need to track our thumb state
67 out.line('const uint8_t thumb;')
62 for t in terminals: 68 for t in terminals:
63 out.line('const %s _%s_instance;' % (t, t)) 69 out.line('const %s _%s_instance;' % (t, t))
64 70
65 out.line('DecoderState() :') 71 out.line('DecoderState(uint8_t thumb) :')
66 first = True 72 # Pass through thumb initialization
73 out.line('thumb(thumb)')
67 for t in terminals: 74 for t in terminals:
68 if first: 75 out.line(',_%s_instance()' % t)
69 out.line('_%s_instance()' % t)
70 else:
71 out.line(',_%s_instance()' % t)
72 first = False
73 out.line('{}') 76 out.line('{}')
74 77
75 out.exit_block(';') 78 out.exit_block(';')
76 79
77 80
78 def _generate_prototypes(tables, out): 81 def _generate_prototypes(name, tables, out):
79 out.block_comment('Prototypes for static table-matching functions.') 82 out.block_comment('Prototypes for static table-matching functions.')
80 for t in tables: 83 for t in tables:
81 out.line('static inline const ClassDecoder &decode_%s(' 84 out.line('static inline const ClassDecoder &%s_decode_%s('
82 'const Instruction insn, const DecoderState *state);' % t.name) 85 'const Instruction insn, const DecoderState *state);' %
86 (name, t.name))
83 87
84 def _generate_implementations(tables, out): 88 def _generate_implementations(name, tables, out):
85 out.block_comment('Table-matching function implementations.') 89 out.block_comment('Table-matching function implementations.')
86 for t in tables: 90 for t in tables:
87 out.line() 91 out.line()
88 _generate_table(t, out) 92 _generate_table(name, t, out)
89 93
90 94
91 def _generate_init_function(out): 95 def _generate_init_function(out):
92 out.enter_block('const DecoderState *init_decode()') 96 out.enter_block('const DecoderState *init_decode(uint8_t thumb)')
93 out.line('return new DecoderState;') 97 out.line('return new DecoderState(thumb);')
94 out.exit_block() 98 out.exit_block()
95 99
96 out.enter_block('void delete_state(const DecoderState *state)') 100 out.enter_block('void delete_state(const DecoderState *state)')
97 out.line('delete (DecoderState *)state;') 101 out.line('delete (DecoderState *)state;')
98 out.exit_block() 102 out.exit_block()
99 103
100 def _generate_entry_point(initial_table_name, out): 104 def _generate_entry_point(arm_table_name, thumb_table_name, out):
101 out.enter_block('const ClassDecoder &decode(const Instruction insn, ' 105 out.enter_block('const ClassDecoder &decode(const Instruction insn, '
102 'const DecoderState *state)') 106 'const DecoderState *state)')
103 out.line('return decode_%s(insn, (DecoderState *)state);' 107 out.enter_block('if (state->thumb)')
104 % initial_table_name) 108 out.line('return thumb_decode_%s(insn, (DecoderState *)state);'
109 % thumb_table_name)
110 out.exit_block()
111 out.enter_block('else')
112 out.line('return arm_decode_%s(insn, (DecoderState *)state);'
113 % arm_table_name)
114 out.exit_block()
105 out.exit_block() 115 out.exit_block()
106 116
107 117
108 def _generate_table(table, out): 118 def _generate_table(name, table, out):
109 """Generates the implementation of a single table.""" 119 """Generates the implementation of a single table."""
110 out.block_comment( 120 out.block_comment(
111 'Implementation of table %s.' % table.name, 121 'Implementation of table %s.' % table.name,
112 'Specified by: %s.' % table.citation 122 'Specified by: %s.' % table.citation
113 ) 123 )
114 out.enter_block('static inline const ClassDecoder &decode_%s(' 124 out.enter_block('static inline const ClassDecoder &%s_decode_%s('
115 'const Instruction insn, const DecoderState *state)' % table.name) 125 'const Instruction insn, const DecoderState *state)' %
126 (name, table.name))
116 127
117 optimized = dgen_opt.optimize_rows(table.rows) 128 optimized = dgen_opt.optimize_rows(table.rows)
118 print ("Table %s: %d rows minimized to %d" 129 print ("Table %s: %d rows minimized to %d"
119 % (table.name, len(table.rows), len(optimized))) 130 % (table.name, len(table.rows), len(optimized)))
131 #out.line("printf(\"mrm DEBUG: Flowing through table " + table.name +
132 # " decoding %x\\n\", insn.bits(31, 0));")
120 for row in sorted(optimized): 133 for row in sorted(optimized):
121 exprs = ["(%s)" % p.to_c_expr('insn') for p in row.patterns] 134 exprs = ["(%s)" % p.to_c_expr('insn') for p in row.patterns]
122 out.enter_block('if (%s)' % ' && '.join(exprs)) 135 out.enter_block('if (%s)' % ' && '.join(exprs))
123 136
124 if row.action.startswith('='): 137 if row.action.startswith('='):
125 _generate_terminal(row.action[1:], out) 138 _generate_terminal(row.action[1:], out)
126 elif row.action.startswith('->'): 139 elif row.action.startswith('->'):
127 _generate_table_change(row.action[2:], out) 140 _generate_table_change(name, row.action[2:], out)
128 else: 141 else:
129 raise Exception('Bad table action: %s' % row.action) 142 raise Exception('Bad table action: %s' % row.action)
130 143
131 out.exit_block() 144 out.exit_block()
132 out.line() 145 out.line()
133 146
134 _generate_safety_net(table, out) 147 _generate_safety_net(table, out)
135 out.exit_block() 148 out.exit_block()
136 149
137 150
138 def _generate_terminal(name, out): 151 def _generate_terminal(name, out):
139 out.line('return state->_%s_instance;' % name) 152 out.line('return state->_%s_instance;' % name)
140 153
141 154
142 def _generate_table_change(name, out): 155 def _generate_table_change(mode, name, out):
143 out.line('return decode_%s(insn, state);' % name) 156 out.line('return %s_decode_%s(insn, state);' % (mode, name))
144 157
145 158
146 def _generate_safety_net(table, out): 159 def _generate_safety_net(table, out):
147 out.line('// Catch any attempt to fall through...') 160 out.line('// Catch any attempt to fall through...')
148 out.line('fprintf(stderr, "TABLE IS INCOMPLETE: %s could not parse %%08X",' 161 out.line('fprintf(stderr, "TABLE IS INCOMPLETE: %s could not parse %%08X",'
149 'insn.bits(31,0));' % table.name) 162 'insn.bits(31,0));' % table.name)
150 _generate_terminal('Forbidden', out) 163 _generate_terminal('Forbidden', out)
151 164
152 165
153 class COutput(object): 166 class COutput(object):
(...skipping 25 matching lines...) Expand all
179 return ' ' * self._indent 192 return ' ' * self._indent
180 193
181 194
182 def each_index_pair(sequence): 195 def each_index_pair(sequence):
183 """Utility method: Generates each unique index pair in sequence.""" 196 """Utility method: Generates each unique index pair in sequence."""
184 for i in range(0, len(sequence)): 197 for i in range(0, len(sequence)):
185 for j in range(i + 1, len(sequence)): 198 for j in range(i + 1, len(sequence)):
186 yield (i, j) 199 yield (i, j)
187 200
188 201
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698