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

Side by Side Diff: src/trusted/validator_arm/dgen_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
OLDNEW
1 #!/usr/bin/python 1 #!/usr/bin/python
2 # 2 #
3 # Copyright 2012 The Native Client Authors. All rights reserved. 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 4 # Use of this source code is governed by a BSD-style license that can be
5 # be found in the LICENSE file. 5 # found in the LICENSE file.
6 # 6 #
7 7
8 """ 8 """
9 Responsible for generating the decoder based on parsed table representations. 9 Responsible for generating the decoder based on parsed table representations.
10 """ 10 """
11 11
12 import dgen_opt 12 import dgen_opt
13 13
14 def generate_decoder_h(tables, decoder_name, filename, named_decoders, out): 14 def generate_decoder_h(tables, decoder_name, filename, named_decoders, out):
15 """Entry point to the decoder for .h file. 15 """Entry point to the decoder for .h file.
16 16
17 Args: 17 Args:
18 tables: list of Table objects to process. 18 tables: list of Table objects to process.
19 decoder_name: The name of the decoder state to build. 19 decoder_name: The name of the decoder state to build.
20 filename: The (localized) name for the .h file. 20 filename: The (localized) name for the .h file.
21 named_decoders: If true, generate a decoder state with named instances. 21 named_decoders: If true, generate a decoder state with named instances.
22 out: a COutput object to write to. 22 out: a COutput object to write to.
23 """ 23 """
24 if len(tables) == 0: raise Exception('No tables provided.') 24 if len(tables) == 0: raise Exception('No tables provided.')
25 25
26 ifdef_name = _generate_ifdef_name(filename) 26 ifdef_name = _generate_ifdef_name(filename)
27 named_prefix = ''
28 if named_decoders:
29 named_prefix = 'Named'
30 27
31 _generate_header(out) 28 _generate_header(out)
32 out.line() 29 if named_decoders:
robertm 2012/04/11 01:28:43 this is getting really hard to understand, maybe i
Karl 2012/04/16 23:18:10 Done.
30 _generate_not_tcb(out)
33 out.line("#ifndef %s" % ifdef_name) 31 out.line("#ifndef %s" % ifdef_name)
34 out.line("#define %s" % ifdef_name) 32 out.line("#define %s" % ifdef_name)
35 out.line() 33 out.line()
36 out.line('#include "native_client/src/trusted/validator_arm/decode.h"') 34 out.line('#include "native_client/src/trusted/validator_arm/decode.h"')
37 out.line() 35 if named_decoders:
38 out.line('namespace nacl_arm_dec {') 36 out.line('#include "native_client/src/trusted/validator_arm/'
37 'named_class_decoder.h"')
39 out.line() 38 out.line()
40 if named_decoders: 39 if named_decoders:
41 _generate_named_decoder_classes(tables, named_prefix, out) 40 _generate_rule_classes(tables, out)
42 _generate_decoder_state_type(tables, decoder_name, named_prefix, out) 41 out.line('namespace nacl_arm_%s {' % ('test' if named_decoders else 'dec'))
42 out.line()
43 if named_decoders:
44 _generate_named_decoder_classes(tables, out)
45 _generate_decoder_state_type(tables, decoder_name, named_decoders, out)
43 out.line('} // namespace') 46 out.line('} // namespace')
44 out.line("#endif // %s" % ifdef_name) 47 out.line("#endif // %s" % ifdef_name)
45 48
46 49
47 def generate_decoder_cc(tables, decoder_name, filename, named_decoders, out): 50 def generate_decoder_cc(tables, decoder_name, filename, named_decoders, out):
48 """Entry point to the decoder for .cc file 51 """Entry point to the decoder for .cc file
49 52
50 Args: 53 Args:
51 tables: list of Table objects to process. 54 tables: list of Table objects to process.
52 decoder_name: The name of the decoder state to build. 55 decoder_name: The name of the decoder state to build.
53 filename: The (localized) name for the .h file. 56 filename: The (localized) name for the .h file.
54 named_decoders: If true, generate a decoder state with named instances. 57 named_decoders: If true, generate a decoder state with named instances.
55 out: a COutput object to write to. 58 out: a COutput object to write to.
56 """ 59 """
57 if len(tables) == 0: raise Exception('No tables provided.') 60 if len(tables) == 0: raise Exception('No tables provided.')
58 61
59 named_prefix = '' 62 _generate_header(out)
60 if named_decoders: 63 if named_decoders:
61 named_prefix = 'Named' 64 _generate_not_tcb(out)
62
63 _generate_header(out)
64 out.line()
65 out.line('#include "%s"' % (filename[:-2] + 'h')) 65 out.line('#include "%s"' % (filename[:-2] + 'h'))
66 out.line(); 66 out.line();
67 out.line('#include <stdio.h>') 67 out.line('#include <stdio.h>')
68 out.line() 68 out.line()
69 out.line('namespace nacl_arm_dec {') 69 if named_decoders:
70 out.line('using nacl_arm_dec::ClassDecoder;')
71 out.line('using nacl_arm_dec::Instruction;')
72 out.line()
73 out.line('namespace nacl_arm_%s {' % ('test' if named_decoders else 'dec'))
70 out.line() 74 out.line()
71 if named_decoders: 75 if named_decoders:
72 _generate_named_decoder_classes_impls(tables, named_prefix, out) 76 _generate_named_decoder_classes_impls(tables, out)
73 _generate_prototypes(tables, decoder_name, named_prefix, out) 77 _generate_implementations(tables, decoder_name, named_decoders, out)
74 _generate_implementations(tables, decoder_name, named_prefix, out) 78 _generate_constructors(tables, decoder_name, named_decoders, out)
75 _generate_constructors(tables, decoder_name, named_prefix, out) 79 _generate_entry_point(decoder_name, named_decoders, tables[0].name, out)
76 _generate_entry_point(decoder_name, named_prefix, tables[0].name, out)
77 out.line('} // namespace') 80 out.line('} // namespace')
78 81
79 82
83 def generate_tests_cc(tables, out):
84 if len(tables) == 0: raise Exception('No tables provided.')
85
86 _generate_header(out)
87 _generate_not_tcb(out)
88 out.line('#include "gtest/gtest.h"')
89 out.line('#include "native_client/src/trusted/validator_arm/'
90 'inst_classes_testers.h"')
91 out.line()
92 out.line('namespace nacl_arm_test {')
93 out.line()
94 _generate_rule_testers(tables, out)
95 _generate_tester(out)
96 _generate_test_patterns(tables, out)
97 out.line('} // namespace')
98 out.line()
99 _generate_test_main(out)
100
101 def _named(name, named_decoders):
102 """ Adds 'Named' prefix to name if named_decoders """
103 return 'Named' + name if named_decoders else name
104
80 def _generate_ifdef_name(filename): 105 def _generate_ifdef_name(filename):
106 """ Generates the ifdef name to use for the given filename"""
81 return filename.replace("/", "_").replace(".", "_").upper() + "_" 107 return filename.replace("/", "_").replace(".", "_").upper() + "_"
82 108
109 def _internalize_component(components):
110 """ Removes an element from components, internalizes the value, and
111 returns the internalized value"
112 """
113 if components:
114 c = components[0]
115 components.remove(c)
116 return None if c == "None" else c
117
118 def _terminal_components(terminal):
119 """ Returns the components of a terminal. That is, a four tuple
120 of the form:
121 (class, rule_name, pattern, constraints)
122 where
123 class - The decoder class to return.
124 rule_name - The arm rule that applies
125 pattern - The bit pattern associated with the arm rule
126 constrainst - Name defining constraints to apply.
127 """
128 components = terminal.split()
129 cls = _internalize_component(components)
130 rule = _internalize_component(components)
131 pattern = _internalize_component(components)
132 constraints = _internalize_component(components)
133 return (cls, rule, pattern, constraints)
134
135 def _terminal_name(terminal, named_decoders = False):
136 """ Returns the terminal name from the terminal action components,
137 unless named_decoders is true and there is a rule name in the
138 action components. In the latter case, the rule name is returned.
139 """
140 components = _terminal_components(terminal)
141 return components[1] if named_decoders and components[1] else components[0]
142
143 def _table_terminals(tables):
144 """ Returns the set of terminals (i.e. actions) defined in the given
145 tables.
146 """
147 terminals = set()
148 for t in tables:
149 for r in t.rows:
150 if r.action.startswith('='):
151 terminals.add(r.action[1:])
152 return terminals
153
154 def _named_terminals(tables, named_decoders):
155 """ Returns the set of (named) class names in the given tables. """
156 terminals = set()
157 for t in _table_terminals(tables):
158 terminals.add(_terminal_name(t, named_decoders))
159 return terminals
160
83 def _generate_header(out): 161 def _generate_header(out):
84 out.block_comment( 162 out.block_comment(
85 'Copyright 2012 The Native Client Authors. All rights reserved.', 163 'Copyright 2012 The Native Client Authors. All rights reserved.',
86 'Use of this source code is governed by a BSD-style license that can', 164 'Use of this source code is governed by a BSD-style license that can',
87 'be found in the LICENSE file.', 165 'be found in the LICENSE file.',
88 ) 166 )
89 out.line() 167 out.line()
90 out.block_comment('DO NOT EDIT: GENERATED CODE') 168 out.block_comment('DO NOT EDIT: GENERATED CODE')
169 out.line()
91 170
92 def _table_terminals(tables): 171 def _generate_not_tcb(out):
93 terminals = set() 172 out.line('#ifndef NACL_TRUSTED_BUT_NOT_TCB')
94 for t in tables: 173 out.line('#error("This file is not meant for use in the TCB")')
95 for r in t.rows: 174 out.line('#endif')
96 if r.action.startswith('='): 175 out.line()
97 terminals.add(r.action[1:])
98 return terminals
99 176
100 def _generate_named_decoder_classes(tables, named_prefix, out): 177 def _generate_rule_class(term, out):
101 for t in _table_terminals(tables): 178 """ Generates an instance class for the rule name of the terminal,
102 out.enter_block('struct %s%s : public %s' % (named_prefix, t, t)) 179 if the terminal has one. This ensures that it will have a different
103 out.line('virtual ~%s%s() {}' % (named_prefix, t)) 180 name than the terminal class, making it easier to identify rules
104 out.line('virtual const char* name() const;') 181 that overlap.
182 """
183 components = _terminal_components(term)
184 if components[1]:
185 out.enter_block('class %s : public %s' % (components[1], components[0]))
186 out.visibility('public')
187 out.line('virtual ~%s() {}' % components[1])
105 out.exit_block(';') 188 out.exit_block(';')
106 out.line() 189 out.line()
107 190
108 def _generate_named_decoder_classes_impls(tables, named_prefix, out): 191 def _generate_rule_classes(tables, out):
192 """ Generates an instance class for each rule name defined in the tables.
193 This ensures that each rule name will define a decoder class with the
194 same name as the rule, making test errors easier to understand.
195 """
196 out.block_comment('Define rule decoder classes')
197 out.line('namespace nacl_arm_dec {');
198 out.line()
109 for t in _table_terminals(tables): 199 for t in _table_terminals(tables):
110 out.enter_block('const char* %s%s::name() const' % (named_prefix, t)); 200 _generate_rule_class(t, out)
111 out.line('return "%s";' % t) 201 out.line('} // namespace nacl_arm_dec')
202 out.line()
203
204 def _generate_named_decoder_classes(tables, out):
205 """ Generates a named decoder class for each type of generated
206 decoder class in the decoder state.
207 """
208 out.block_comment('Define name class decoders for each class decoder')
209 out.line()
210 for t in _named_terminals(tables, True):
211 out.enter_block('class %s : public NamedClassDecoder' %
robertm 2012/04/11 01:28:43 this would also benefit from a template
Karl 2012/04/16 23:18:10 Done.
212 _named(t, True))
213 out.visibility('public');
214 out.line('%s();' % _named(t, True))
215 out.line('virtual ~%s() {}' % _named(t, True))
216 out.visibility('private')
217 out.line('nacl_arm_dec::%s named_decoder_;' % t)
218 out.exit_block(';')
219 out.line()
220
221 def _generate_named_decoder_classes_impls(tables, out):
222 """ Generates method implementations for each generated
223 named decoder class
224 """
225 for t in _named_terminals(tables, True):
226 out.enter_constructor_header('%s::%s()' %
227 (_named(t, True),
228 _named(t, True)))
229 out.line('NamedClassDecoder(named_decoder_, "%s")' % t)
230 out.exit_constructor_header()
231 out.enter_block()
112 out.exit_block() 232 out.exit_block()
113 out.line() 233 out.line()
114 234
115 def _generate_decoder_state_type(tables, decoder_name, named_prefix, out): 235 def _generate_decoder_state_type(tables, decoder_name, named_decoders, out):
116 cls_name = '%s%s' % (named_prefix, decoder_name) 236 """ Generates the deocder state that dispatches the correct class
237 decoder for any instruction.
238 """
117 out.block_comment( 239 out.block_comment(
118 'Defines a stateless decoder class selector for instructions' 240 'Defines a stateless decoder class selector for instructions'
119 ) 241 )
120 out.block_comment('Define the class decoders used by this decoder state.') 242 out.enter_block('class %s : nacl_arm_dec::DecoderState' %
121 out.enter_block('class %s : DecoderState' % cls_name) 243 _named(decoder_name, named_decoders))
122 out.visibility('public') 244 out.visibility('public')
123 out.comment('Generates an instance of a decoder state.') 245 out.block_comment('Generates an instance of a decoder state.')
124 out.line('explicit %s();' % cls_name) 246 out.line('explicit %s();' % _named(decoder_name, named_decoders))
125 out.line('virtual ~%s();' % cls_name) 247 out.line('virtual ~%s();' % _named(decoder_name, named_decoders))
126 out.line() 248 out.line()
127 out.comment('Parses the given instruction, returning the decoder to use.') 249 out.block_comment(
128 out.line('virtual const class ClassDecoder ' 250 'Parses the given instruction, returning the decoder to use.')
129 '&decode(const Instruction) const;') 251 if named_decoders:
130 out.line() 252 out.line('const NamedClassDecoder &decode_named('
131 out.comment('Define the decoders to use in this decoder state') 253 ' const nacl_arm_dec::Instruction) const;')
132 for t in _table_terminals(tables): 254 out.line('virtual const class nacl_arm_dec::ClassDecoder')
133 out.line('%s%s %s_instance_;' % (named_prefix, t, t)) 255 out.line(' &decode(const nacl_arm_dec::Instruction) const;')
134 out.line() 256 if not named_decoders:
135 out.visibility('private') 257 out.line()
136 out.comment("Don't allow the following!") 258 out.visibility('private')
137 out.line('explicit %s(const %s&);' % (cls_name, cls_name)) 259 _generate_fields(tables, named_decoders, out)
138 out.line('void operator=(const %s&);' % cls_name) 260 if named_decoders:
261 out.line()
262 out.visibility('private')
263 _generate_prototypes(tables, named_decoders, out)
139 out.exit_block(';') 264 out.exit_block(';')
140 out.line() 265 out.line()
141 266
142 def _generate_prototypes(tables, decoder_name, named_prefix, out): 267 def _generate_fields(tables, named_decoders, out):
268 """ Generates an instance field for each class decoder used by
269 the decoder state, so that only one instance exists.
270 """
271 out.block_comment('Define the class decoders used by this decoder state.')
272 for t in _named_terminals(tables, named_decoders):
273 out.line('const %s %s_instance_;' % (_named(t, named_decoders), t))
274 out.line()
275
276 def _generate_prototypes(tables, named_decoders, out):
277 """ Generate parsing method prototypes for the decoder state. """
143 out.block_comment('Prototypes for static table-matching functions.') 278 out.block_comment('Prototypes for static table-matching functions.')
144 for t in tables: 279 for t in tables:
145 280 out.line('inline const %s &decode_%s('
146 out.line('static inline const ClassDecoder &decode_%s(' % t.name) 281 ' const nacl_arm_dec::Instruction insn) const;'
147 out.line(' const Instruction insn, const %s%s *state);' % 282 % (_named('ClassDecoder', named_decoders), t.name))
148 (named_prefix, decoder_name))
149 out.line() 283 out.line()
150 284
151 def _generate_implementations(tables, decoder_name, named_prefix, out): 285 def _generate_implementations(tables, decoder_name, named_decoders, out):
286 """ Generate bodies for each parsing method defined for the
287 decoder state.
288 """
152 out.block_comment('Table-matching function implementations.') 289 out.block_comment('Table-matching function implementations.')
153 for t in tables: 290 for t in tables:
154 out.line() 291 out.line()
155 _generate_table(t, decoder_name, named_prefix, out) 292 _generate_table(t, decoder_name, named_decoders, out)
156 out.line()
157 293
158 def _generate_constructors(tables, decoder_name, named_prefix, out): 294 def _generate_constructors(tables, decoder_name, named_decoders, out):
159 out.enter_constructor_header('%s%s::%s%s()' % (named_prefix, decoder_name, 295 """ Generate the constructor/destructor for the decoder state."""
160 named_prefix, decoder_name)) 296 out.enter_constructor_header('%s::%s()' %
297 (_named(decoder_name, named_decoders),
298 _named(decoder_name, named_decoders)))
161 out.line('DecoderState()') 299 out.line('DecoderState()')
162 for t in _table_terminals(tables): 300 for t in _named_terminals(tables, named_decoders):
163 out.line(', %s_instance_()' % t) 301 out.line(', %s_instance_()' % t)
164 out.exit_constructor_header() 302 out.exit_constructor_header()
165 out.enter_block() 303 out.enter_block()
166 out.exit_block() 304 out.exit_block()
167 out.line() 305 out.line()
168 out.enter_block('%s%s::~%s%s()' % (named_prefix, decoder_name, 306 out.enter_block('%s::~%s()' % (_named(decoder_name, named_decoders),
169 named_prefix, decoder_name)) 307 _named(decoder_name, named_decoders)))
170 out.exit_block() 308 out.exit_block()
171 out.line() 309 out.line()
172 310
173 def _generate_entry_point(decoder_name, named_prefix, initial_table_name, out): 311 def _generate_entry_point(decoder_name, named_decoders,
312 initial_table_name, out):
313 """ Generate method bodies for the top-level parsing method(s) of
314 the decoder state.
315 """
174 out.enter_block( 316 out.enter_block(
175 'const ClassDecoder &%s%s::decode(const Instruction insn) const' % 317 'const ClassDecoder &%s::decode(const Instruction insn) const' %
176 (named_prefix, decoder_name)) 318 _named(decoder_name, named_decoders))
177 out.line('return decode_%s(insn, this);' 319 if named_decoders:
178 % initial_table_name) 320 out.line('return decode_named(insn).named_decoder();')
321 else:
322 out.line('return decode_%s(insn);' % initial_table_name)
179 out.exit_block() 323 out.exit_block()
180 out.line() 324 out.line()
325 if named_decoders:
326 out.line('const NamedClassDecoder &%s::decode_named(' %
327 _named(decoder_name, True))
328 out.enter_block(' const Instruction insn) const')
329 out.line('return decode_%s(insn);' % initial_table_name)
330 out.exit_block()
331 out.line()
181 332
182 333 def _generate_table(table, decoder_name, named_decoders, out):
183 def _generate_table(table, decoder_name, named_prefix, out): 334 """Generates the implementation of a single parsing table."""
184 """Generates the implementation of a single table."""
185 out.block_comment( 335 out.block_comment(
186 'Implementation of table %s.' % table.name, 336 'Implementation of table %s.' % table.name,
187 'Specified by: %s.' % table.citation 337 'Specified by: %s.' % table.citation
188 ) 338 )
189 out.line('static inline const ClassDecoder &decode_%s(' %table.name) 339 out.enter_block('const %s &%s::decode_%s(const Instruction insn) const' %
190 out.enter_block(' const Instruction insn, const %s%s *state)' % 340 (_named('ClassDecoder', named_decoders),
191 (named_prefix, decoder_name)) 341 _named(decoder_name, named_decoders),
342 table.name))
192 343
193 optimized = dgen_opt.optimize_rows(table.rows) 344 # If not named decoder classes, optimize as much as possible. That
345 # is, only consider the decoder class name when merging. If generating
346 # named decoder classes, separate base on rule name as well.
347 num_action_cols = 2 if named_decoders else 1
348 optimized = dgen_opt.optimize_rows(table.rows_filtered(num_action_cols))
194 print ("Table %s: %d rows minimized to %d" 349 print ("Table %s: %d rows minimized to %d"
195 % (table.name, len(table.rows), len(optimized))) 350 % (table.name, len(table.rows), len(optimized)))
196 for row in sorted(optimized): 351 for row in sorted(optimized):
197 exprs = ["(%s)" % p.to_c_expr('insn') for p in row.patterns] 352 exprs = ["(%s)" % p.to_c_expr('insn') for p in row.patterns]
198 out.enter_block('if (%s)' % ' && '.join(exprs)) 353 out.enter_block('if (%s)' % ' && '.join(exprs))
199 354
200 if row.action.startswith('='): 355 if row.action.startswith('='):
201 _generate_terminal(row.action[1:], out) 356 _generate_terminal(_terminal_name(row.action[1:],
357 named_decoders),
358 out)
202 elif row.action.startswith('->'): 359 elif row.action.startswith('->'):
203 _generate_table_change(row.action[2:], out) 360 _generate_table_change(row.action[2:], out)
204 else: 361 else:
205 raise Exception('Bad table action: %s' % row.action) 362 raise Exception('Bad table action: %s' % row.action)
206 363
207 out.exit_block() 364 out.exit_block()
208 out.line() 365 out.line()
209 366
210 _generate_safety_net(table, out) 367 _generate_safety_net(table, out)
211 out.exit_block() 368 out.exit_block()
369 out.line()
212 370
213 def _generate_terminal(name, out): 371 def _generate_terminal(name, out):
214 out.line('return state->%s_instance_;' % name) 372 out.line('return %s_instance_;' % name)
215 373
216 def _generate_table_change(name, out): 374 def _generate_table_change(name, out):
217 out.line('return decode_%s(insn, state);' % name) 375 out.line('return decode_%s(insn);' % name)
218 376
219 def _generate_safety_net(table, out): 377 def _generate_safety_net(table, out):
220 out.line('// Catch any attempt to fall through...') 378 out.line('// Catch any attempt to fall through...')
221 out.line('fprintf(stderr, "TABLE IS INCOMPLETE: %s could not parse %%08X",' 379 out.line('fprintf(stderr, "TABLE IS INCOMPLETE: %s could not parse %%08X",'
222 'insn.bits(31,0));' % table.name) 380 'insn.bits(31,0));' % table.name)
223 _generate_terminal('Forbidden', out) 381 _generate_terminal('Forbidden', out)
224 382
383 def _rule_tester(rule):
384 return '%s_Tester' % rule
385
386 def _rule_base_tester(cls, constraints):
387 return '%sTester%s' % (cls, (constraints if constraints else ''))
388
389 def _generate_rule_tester(term, out):
390 components = _terminal_components(term)
391 cls = components[0]
392 rule = components[1]
393 pattern = components[2]
394 constraints = components[3]
395 if cls and rule and pattern:
396 rule_tester = _rule_tester(rule)
397 rule_base_tester = _rule_base_tester(cls, constraints)
398 out.line('class %s ' % rule_tester)
399 out.enter_block(' : public %s' % rule_base_tester)
400 out.visibility('public')
401 out.line('%s()' % rule_tester)
402 out.line(' : %s(' % rule_base_tester)
403 out.line(' state_.%s_instance_)' % _terminal_name(term, True))
404 out.enter_block()
405 out.exit_block()
406 out.exit_block(';')
407 out.line()
408
409 def _generate_rule_testers(tables, out):
410 out.block_comment('Tester classes for decoder rules')
411 out.line()
412 for t in _table_terminals(tables):
413 _generate_rule_tester(t, out)
414
415 def _generate_tester(out):
416 out.block_comment('Defines a gtest testing harness for testing',
417 'Arm32 instructions.')
418 out.enter_block('class Arm32InstructionTests : public ::testing::Test')
419 out.visibility('protected')
420 out.line('Arm32InstructionTests() {}')
421 out.exit_block(';')
422 out.line()
423
424 def _generate_test_pattern(term, out):
425 components = _terminal_components(term)
426 cls = components[0]
427 rule = components[1]
428 pattern = components[2]
429 if cls and rule and pattern:
430 rule_tester = _rule_tester(rule)
431 out.enter_block('TEST_F(Arm32InstructionTests, %s_Test)' % rule_tester)
432 out.line('%s tester;' % rule_tester)
433 out.line('tester.Test("%s");' % pattern)
434 out.exit_block()
435 out.line()
436
437 def _generate_test_patterns(tables, out):
438 out.block_comment('Test coverage of rule patterns')
439 out.line()
440 for t in _table_terminals(tables):
441 _generate_test_pattern(t, out)
442
443 def _generate_test_main(out):
444 out.block_comment('Test driver function.')
445 out.enter_block('int main(int argc, char *argv[])')
446 out.line('testing::InitGoogleTest(&argc, argv);')
447 out.line('return RUN_ALL_TESTS();')
448 out.exit_block()
449
225 450
226 class COutput(object): 451 class COutput(object):
227 """Provides nicely-formatted C++ output.""" 452 """Provides nicely-formatted C++ output."""
228 453
229 def __init__(self, out): 454 def __init__(self, out):
230 self._out = out 455 self._out = out
231 self._indent = 0 456 self._indent = 0
232 457
233 def line(self, str = ''): 458 def line(self, str = ''):
234 self._out.write(self._tabs()) 459 self._out.write(self._tabs())
(...skipping 30 matching lines...) Expand all
265 490
266 def _tabs(self): 491 def _tabs(self):
267 return ' ' * self._indent 492 return ' ' * self._indent
268 493
269 494
270 def each_index_pair(sequence): 495 def each_index_pair(sequence):
271 """Utility method: Generates each unique index pair in sequence.""" 496 """Utility method: Generates each unique index pair in sequence."""
272 for i in range(0, len(sequence)): 497 for i in range(0, len(sequence)):
273 for j in range(i + 1, len(sequence)): 498 for j in range(i + 1, len(sequence)):
274 yield (i, j) 499 yield (i, j)
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698