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

Side by Side Diff: src/trusted/validator_arm/dgen_core.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 2009 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 # Copyright 2009, Google Inc.
7 # 6 #
8 7
9 """ 8 """
10 The core object model for the Decoder Generator. The dg_input and dg_output 9 The core object model for the Decoder Generator. The dg_input and dg_output
11 modules both operate in terms of these classes. 10 modules both operate in terms of these classes.
12 """ 11 """
13 12
14 import re
15
16 def _popcount(int): 13 def _popcount(int):
17 """Returns the number of 1 bits in the input.""" 14 """Returns the number of 1 bits in the input."""
18 count = 0 15 count = 0
19 for bit in range(0, 32): 16 for bit in range(0, 32):
20 count = count + ((int >> bit) & 1) 17 count = count + ((int >> bit) & 1)
21 return count 18 return count
22 19
23 20
24 class BitPattern(object): 21 class BitPattern(object):
25 """A pattern for matching strings of bits. See parse() for syntax.""" 22 """A pattern for matching strings of bits. See parse() for syntax."""
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
78 elif c == 'x' or c == 'X': 75 elif c == 'x' or c == 'X':
79 mask = mask << 1 76 mask = mask << 1
80 value = value << 1 77 value = value << 1
81 else: 78 else:
82 raise Exception('Invalid characters in pattern %s' % pattern) 79 raise Exception('Invalid characters in pattern %s' % pattern)
83 80
84 mask = mask << lo_bit 81 mask = mask << lo_bit
85 value = value << lo_bit 82 value = value << lo_bit
86 return BitPattern(mask, value, op) 83 return BitPattern(mask, value, op)
87 84
85 @staticmethod
86 def parse_catch(pattern, hi_bit, lo_bit):
87 """"Calls parse with given arguments, and catches exceptions
88 raised. Prints raised exceptions and returns None.
89 """
90 try:
91 return BitPattern.parse(pattern, hi_bit, lo_bit);
92 except Exception as ex:
93 print "Error: %s" % ex
94 return None
95
88 def __init__(self, mask, value, op): 96 def __init__(self, mask, value, op):
89 """Initializes a BitPattern. 97 """Initializes a BitPattern.
90 98
91 Args: 99 Args:
92 mask: an integer with 1s in the bit positions we care about (e.g. 100 mask: an integer with 1s in the bit positions we care about (e.g.
93 those that are not X) 101 those that are not X)
94 value: an integer that would match our pattern, subject to the mask. 102 value: an integer that would match our pattern, subject to the mask.
95 op: either '==' or '!=', if the pattern is positive or negative, 103 op: either '==' or '!=', if the pattern is positive or negative,
96 respectively. 104 respectively.
97 """ 105 """
(...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after
199 Because we don't use the column information for very much, we don't give 207 Because we don't use the column information for very much, we don't give
200 it a type -- we store it as a list of tuples. 208 it a type -- we store it as a list of tuples.
201 209
202 Args: 210 Args:
203 name: the name of the column (for diagnostic purposes only). 211 name: the name of the column (for diagnostic purposes only).
204 hi_bit: the leftmost bit included. 212 hi_bit: the leftmost bit included.
205 lo_bit: the rightmost bit included. 213 lo_bit: the rightmost bit included.
206 """ 214 """
207 self._columns.append( (name, hi_bit, lo_bit) ) 215 self._columns.append( (name, hi_bit, lo_bit) )
208 216
209 def add_row(self, col_patterns, action_string): 217 def add_row(self, patterns, action, arch):
210 """Adds a row to the table. 218 """Adds a row to the table.
211 Args: 219 Args:
212 col_patterns: a list containing a BitPattern for every column in the 220 patterns: a list containing a BitPattern for every column in the
213 table. 221 table.
214 action_string: a string indicating the action to take; must begin 222 action_string: a string indicating the action to take; must begin
sehr (please use chromium) 2012/04/19 19:52:47 s/action_string/action/
Karl 2012/04/24 19:58:27 Done.
215 with '=' for a terminal instruction class, or '->' for a 223 with '=' for a terminal instruction class, or '->' for a
216 table-change. The action may end with an arch revision in 224 table-change.
217 parentheses. 225 arg: a string defining the architectures it applies to. None
sehr (please use chromium) 2012/04/19 19:52:47 s/arg/arch/
Karl 2012/04/24 19:58:27 Done.
226 implies all.
218 """ 227 """
219 arch = None 228 self.rows.append(Row(patterns, action, arch))
220 m = re.match(r'^(=[A-Za-z0-9_]+)\(([^)]+)\)$', action_string)
221 if m:
222 action_string = m.group(1)
223 arch = m.group(2)
224 229
225 parsed = [] 230 def define_pattern(self, pattern, column):
226 for i in range(0, len(col_patterns)): 231 """Converts the given input pattern (for the given column) to the
227 col = self._columns[i] 232 internal form. Returns None if pattern is bad.
228 parsed.append(BitPattern.parse(col_patterns[i], col[1], col[2])) 233 """
229 self.rows.append(Row(parsed, action_string, arch)) 234 if column >= len(self._columns): return None
235 col = self._columns[column]
236 return BitPattern.parse_catch(pattern, col[1], col[2])
230 237
238 def action_filter(self, names):
239 """Returns a table with DecoderActions reduced to the given field names.
240 Used to optimize out duplicates, depending on context.
241 """
242 table = Table(self.name, self.citation)
243 table._columns = self._columns
244 for r in self.rows:
245 table.add_row(r.patterns, r.action.action_filter(names), r.arch)
246 return table
247
248 class DecoderAction:
249 """An action defining a class decoder to apply.
250
251 Corresponds to the parsed decoder action:
252 decoder_action ::= id (id (word (id)?)?)?
253
254 Fields are:
255 name - Name of class decoder selected.
256 rule - Name of the rule in ARM manual that defines
257 the decoder action.
258 pattern - The placement of 0/1's within any instruction
259 that is matched by the corresponding rule.
260 constraints - Additional constraints that apply to the rule.
261 """
262 def __init__(self, name, rule, pattern, constraints):
263 self.name = name
264 self.rule = rule
265 self.pattern = pattern
266 self.constraints = constraints
267
268 def action_filter(self, names):
269 return DecoderAction(
270 self.name if 'name' in names else None,
271 self.rule if 'rule' in names else None,
272 self.pattern if 'pattern' in names else None,
273 self.constraints if 'constraints' in names else None)
274
275 def __eq__(self, other):
276 return (other.__class__.__name__ == 'DecoderAction'
277 and self.name == other.name
278 and self.rule == other.rule
279 and self.pattern == other.pattern
280 and self.constraints == other.constraints)
281
282 def __cmp__(self, other):
283 # Order lexicographically on type/fields.
284 value = cmp(other.__class__.__name__, 'DecoderAction')
285 if value != 0: return value
286 value = cmp(self.name, other.name)
287 if value != 0: return value
288 value = cmp(self.rule, other.rule)
289 if value != 0: return value
290 value = cmp(self.pattern, other.pattern)
291 if value != 0: return value
292 return cmp(self.constraints, other.constraints)
293
294 def __hash__(self):
295 return (hash('DecoderAction') + hash(self.name) + hash(self.rule) +
296 hash(self.pattern) + hash(self.constraints))
297
298 def __repr__(self):
299 return '=%s %s %s %s' % (self.name, self.rule,
300 self.pattern, self.constraints)
301
302 class DecoderMethod(object):
303 """An action defining a parse method to call.
304
305 Corresponds to the parsed decoder method:
306 decoder_method ::= '->' id
307
308 Fields are:
309 name - The name of the corresponding table (i.e. method) that
310 should be used to continue searching for a matching class
311 decoder.
312 """
313 def __init__(self, name):
314 self.name = name
315
316 def action_filter(self, unused_names):
317 return self
318
319 def __eq__(self, other):
320 return (self.__class__.__name__ == 'DecoderMethod'
321 and self.name == other.name)
322
323 def __cmp__(self, other):
324 # Lexicographically compare types/fields.
325 value = cmp(other.__class__.__name__, 'DecoderMethod')
326 if value != 0: return value
327 return cmp(self.name, other.name)
328
329 def __hash__(self):
330 return hash('DecoderMethod') + hash(self.name)
331
332 def __repr__(self):
333 return '->%s' % self.name
231 334
232 class Row(object): 335 class Row(object):
233 """ A row in a Table.""" 336 """ A row in a Table."""
234 def __init__(self, patterns, action, arch): 337 def __init__(self, patterns, action, arch):
235 """Initializes a Row. 338 """Initializes a Row.
236 Args: 339 Args:
237 patterns: a list of BitPatterns that must match for this Row to 340 patterns: a list of BitPatterns that must match for this Row to
238 match. 341 match.
239 action: the action to be taken if this Row matches. 342 action: the action to be taken if this Row matches.
240 arch: the minimum architecture that this Row can match. 343 arch: the minimum architecture that this Row can match.
(...skipping 29 matching lines...) Expand all
270 self.action, self.arch) 373 self.action, self.arch)
271 374
272 def __cmp__(self, other): 375 def __cmp__(self, other):
273 """Compares two rows, so we can order pattern matches by specificity. 376 """Compares two rows, so we can order pattern matches by specificity.
274 """ 377 """
275 return (cmp(self.patterns, other.patterns) 378 return (cmp(self.patterns, other.patterns)
276 or cmp(self.action, other.action)) 379 or cmp(self.action, other.action))
277 380
278 def __repr__(self): 381 def __repr__(self):
279 return 'Row(%s, %s)' % (repr(self.patterns), repr(self.action)) 382 return 'Row(%s, %s)' % (repr(self.patterns), repr(self.action))
383
384 class Decoder(object):
385 """Defines a class decoder which consists of set of tables.
386
387 A decoder has a primary (i.e. start) table to parse intructions (and
388 select the proper ClassDecoder), as well as a set of additional
389 tables to complete the selection of a class decoder. Instances of
390 this class correspond to the internal representation of parsed
391 decoder tables recognized by dgen_input.py (see that file for
392 details).
393
394 Fields are:
395 primary - The entry parse table to find a class decoder.
396 tables - The (sorted) set of tables defined by a decoder.
397
398 Note: maintains restriction that tables have unique names.
399 """
400
401 def __init__(self):
402 self.primary = None
403 self._is_sorted = False
404 self._tables = []
405
406 def add(self, table):
407 """Adds the table to the set of tables. Returns true if successful.
408 """
409 if filter(lambda(t): t.name == table.name, self._tables):
410 # Table with name already defined, report error.
411 return False
412 else:
413 if not self._tables:
414 self.primary = table
415 self._tables.append(table)
416 self.is_sorted = False
417 return True
418
419 def tables(self):
420 """Returns the sorted (by table name) list of tables"""
421 if self._is_sorted: return self._tables
422 self._tables = sorted(self._tables, key=lambda(tbl): tbl.name)
423 self._is_sorted = True
424 return self._tables
425
426 def action_filter(self, names):
427 """Returns a new set of tables with actions reduced to the set of
428 field names.
429 """
430 decoder = Decoder()
431 decoder._tables = sorted([ t.action_filter(names) for t in self._tables ],
432 key=lambda(tbl): tbl.name)
433 decoder.primary = filter(
434 lambda(t): t.name == self.primary.name, self._tables)[0]
435 return decoder
436
437 def decoders(self):
438 """Returns the sorted sequence of DecoderAction's defined in the tables."""
439 decoders = set()
440 for t in self._tables:
441 for r in t.rows:
442 if r.action.__class__.__name__ == 'DecoderAction':
443 decoders.add(r.action)
444 return sorted(decoders)
445
446 def rules(self):
447 """Returns the sorted sequence of DecoderActions that define
448 the rule field.
449 """
450 return sorted(filter(lambda (r): r.rule, self.decoders()))
OLDNEW
« no previous file with comments | « src/trusted/validator_arm/decoder_tests.cc ('k') | src/trusted/validator_arm/dgen_decoder_output.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698