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

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

Issue 9960043: Finish separation of testing from sel_ldr validation. Also, automate (Closed) Base URL: svn://svn.chromium.org/native_client/trunk/src/native_client/
Patch Set: Created 8 years, 8 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
Property Changes:
Added: svn:eol-style
+ LF
OLDNEW
(Empty)
1 #!/usr/bin/python
2 #
3 # Copyright (c) 2012 The Native Client Authors. All rights reserved.
4 # Use of this source code is governed by a BSD-style license that can be
5 # found in the LICENSE file.
6 #
7
8 """
9 Responsible for generating the decoder based on parsed
10 table representations.
11 """
12
13
14 import dgen_opt
15 import dgen_output
16
17 # This file generates the class decoder Decoder as defined by the
18 # decoder tables. The code is specifically written to minize the
19 # number of decoder classes needed to parse valid ARM
20 # instructions. Many rows in the table use the same decoder class. In
21 # addition, we optimize tables by merging, so long as the same decoder
22 # class is built.
23 #
24 # The following files are generated:
25 #
26 # decoder.h
27 # decoder.cc
28 #
29 # decoder.h declares the generated decoder parser class while
30 # decoder.cc contains the implementation of that decoder class.
31 #
32 # For testing purposes (see dgen_test_output.py) different rules are
robertm 2012/04/17 17:12:19 mention that the other file as a nice description
Karl 2012/04/17 19:28:31 Done.
33 # applied.
34 #
35
36 # Defines the header for decoder.h
37 H_HEADER="""
38 %(FILE_HEADER)s
39
40 #ifndef %(IFDEF_NAME)s
41 #define %(IFDEF_NAME)s
42
43 #include "native_client/src/trusted/validator_arm/decode.h"
44 #include "native_client/src/trusted/validator_arm/inst_classes.h"
45
46 namespace nacl_arm_dec {
47 """
48
49 DECODER_DECLARE_HEADER="""
50 // Defines a stateless decoder class selector for instructions.
51 class %(decoder_name)s : DecoderState {
52 public:
53 explicit %(decoder_name)s();
54 virtual ~%(decoder_name)s();
55
56 // Parses the given instruction, returning the decoder to use.
57 virtual const ClassDecoder& decode(const Instruction) const;
58
59 private:
60 """
61
62 DECODER_DECLARE_METHOD="""
63 inline const ClassDecoder& decode_%(table_name)s(
64 const Instruction insn) const;
65 """
66
67 DECODER_DECLARE_FIELD="""
68 %(decoder)s %(decoder)s_instance_;
69 """
70
71 DECODER_DECLARE_FOOTER="""
72 };
73 """
74
75 H_FOOTER="""
76 } // namespace nacl_arm_dec
77 #endif // %(IFDEF_NAME)s
78 """
79
80 def generate_h(decoder, decoder_name, filename, out):
81 """Entry point to the decoder for .h file.
82
83 Args:
84 decoder: The decoder defined by the list of Table objects to process.
85 decoder_name: The name of the decoder state to build.
86 filename: The (localized) name for the .h file.
87 named_decoders: If true, generate a decoder state with named instances.
88 out: a COutput object to write to.
89 """
90 if not decoder.primary: raise Exception('No tables provided.')
91
92 # Before starting, remove all testing information from the parsed tables.
93 decoder = decoder.action_filter(['name'])
94
95 values = {
96 'FILE_HEADER': dgen_output.HEADER_BOILERPLATE,
97 'IFDEF_NAME': dgen_output.ifdef_name(filename),
98 'decoder_name': decoder_name,
99 }
100 out.write(H_HEADER % values)
101 out.write(DECODER_DECLARE_HEADER % values)
102 for table in decoder.tables():
103 values['table_name'] = table.name
104 out.write(DECODER_DECLARE_METHOD % values)
105 for action in decoder.decoders():
106 values['decoder'] = action.name;
107 out.write(DECODER_DECLARE_FIELD % values)
108 out.write(DECODER_DECLARE_FOOTER % values)
109 out.write(H_FOOTER % values)
110
111 # Defines the header for DECODER.h
112 CC_HEADER="""
113 %(FILE_HEADER)s
114
115 #include "%(header_filename)s"
116
117 #include <stdio.h>
118
119 namespace nacl_arm_dec {
120
121 """
122
123 CONSTRUCTOR_HEADER="""
124 %(decoder_name)s::%(decoder_name)s() : DecoderState()
125 """
126
127 CONSTRUCTOR_FIELD_INIT="""
128 , %(decoder)s_instance_()
129 """
130
131 CONSTRUCTOR_FOOTER="""
132 {}
133
134 %(decoder_name)s::~%(decoder_name)s() {}
135 """
136
137 METHOD_HEADER="""
138 // Implementation of table: %(table_name)s.
139 // Specified by: %(citation)s
140 const ClassDecoder& %(decoder_name)s::decode_%(table_name)s(
141 const Instruction insn) const
142 {
143 """
144
145 METHOD_DISPATCH="""
146 if (%(tests)s)
147 """
148
149 METHOD_DISPATCH_CLASS_DECODER="""
150 return %(decoder)s_instance_;
151 """
152
153 METHOD_DISPATCH_SUBMETHOD="""
154 return decode_%(subtable_name)s(insn);
155 """
156
157 METHOD_FOOTER="""
158 // Catch any attempt to fall though ...
159 fprintf(stderr, "TABLE IS INCOMPLETE: %(table_name)s could not parse %%08X",
160 insn.bits(31, 0));
161 return Forbidden_instance_;
162 }
163 """
164
165 DECODER_METHOD="""
166 const ClassDecoder& %(decoder_name)s::decode(const Instruction insn) const {
167 return decode_%(entry_table_name)s(insn);
168 }
169 """
170
171 CC_FOOTER="""
172 } // namespace nacl_arm_dec
173 """
174
175 def generate_cc(decoder, decoder_name, filename, out):
176 """Implementation of the decoder in .cc file
177
178 Args:
179 decoder: The decoder defined by the list of Table objects to process.
180 decoder_name: The name of the decoder state to build.
181 filename: The (localized) name for the .h file.
182 named_decoders: If true, generate a decoder state with named instances.
183 out: a COutput object to write to.
184 """
185 if not decoder.primary: raise Exception('No tables provided.')
186
187 # Before starting, remove all testing information from the parsed tables.
188 decoder = decoder.action_filter(['name'])
189 values = {
190 'FILE_HEADER': dgen_output.HEADER_BOILERPLATE,
191 'header_filename': filename[:-2] + 'h',
robertm 2012/04/17 17:12:19 maybe assert that file name ends with '.cc'
Karl 2012/04/17 19:28:31 Done.
192 'decoder_name': decoder_name,
193 'entry_table_name': decoder.primary.name,
194 }
195 out.write(CC_HEADER % values)
196 _generate_constructors(decoder, values, out)
197 _generate_methods(decoder, values, out)
198 out.write(DECODER_METHOD % values)
199 out.write(CC_FOOTER % values)
200
201 def _generate_constructors(decoder, values, out):
202 out.write(CONSTRUCTOR_HEADER % values)
203 for decoder in decoder.decoders():
204 values['decoder'] = decoder.name
205 out.write(CONSTRUCTOR_FIELD_INIT % values)
206 out.write(CONSTRUCTOR_FOOTER % values)
207
208 def _generate_methods(decoder, values, out):
209 for table in decoder.tables():
210 opt_rows = sorted(dgen_opt.optimize_rows(table.rows))
211 print ("Table %s: %d rows minimized to %d"
212 % (table.name, len(table.rows), len(opt_rows)))
213
214 values['table_name'] = table.name
215 values['citation'] = table.citation
216 out.write(METHOD_HEADER % values)
217 method_calls = filter(
robertm 2012/04/17 17:12:19 try to replace this with list comprehension (there
Karl 2012/04/17 19:28:31 Done.
218 lambda(r): r.action.__class__.__name__ == 'DecoderMethod', opt_rows)
219 if not method_calls:
220 out.write(" UNREFERENCED_PARAMETER(insn);")
221
222 for row in opt_rows:
223 values['tests'] = ' && '.join(["(%s)" % p.to_c_expr('insn')
robertm 2012/04/17 17:12:19 add a comment explaining the introspection magic -
Karl 2012/04/17 19:28:31 Done.
224 for p in row.patterns])
225 out.write(METHOD_DISPATCH % values)
226 if row.action.__class__.__name__ == 'DecoderAction':
227 values['decoder'] = row.action.name
228 out.write(METHOD_DISPATCH_CLASS_DECODER % values)
229 elif row.action.__class__.__name__ == 'DecoderMethod':
230 values['subtable_name'] = row.action.name
231 out.write(METHOD_DISPATCH_SUBMETHOD % values)
232 else:
233 raise Exception('Bad table action: %s' % repr(row.action))
234 out.write(METHOD_FOOTER % values)
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698