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

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: The action associated with the row. Must either be
215 with '=' for a terminal instruction class, or '->' for a 223 a DecoderAction or a DecoderMethod.
216 table-change. The action may end with an arch revision in 224 arch: a string defining the architectures it applies to. None
217 parentheses. 225 implies all.
218 """ 226 """
219 arch = None 227 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 228
225 parsed = [] 229 def define_pattern(self, pattern, column):
226 for i in range(0, len(col_patterns)): 230 """Converts the given input pattern (for the given column) to the
227 col = self._columns[i] 231 internal form. Returns None if pattern is bad.
228 parsed.append(BitPattern.parse(col_patterns[i], col[1], col[2])) 232 """
229 self.rows.append(Row(parsed, action_string, arch)) 233 if column >= len(self._columns): return None
234 col = self._columns[column]
235 return BitPattern.parse_catch(pattern, col[1], col[2])
230 236
237 def action_filter(self, names):
238 """Returns a table with DecoderActions reduced to the given field names.
239 Used to optimize out duplicates, depending on context.
240 """
241 table = Table(self.name, self.citation)
242 table._columns = self._columns
243 for r in self.rows:
244 table.add_row(r.patterns, r.action.action_filter(names), r.arch)
245 return table
246
247 class DecoderAction:
248 """An action defining a class decoder to apply.
249
250 Corresponds to the parsed decoder action:
251 decoder_action ::= id (id (word (id)?)?)?
252
253 Fields are:
254 name - Name of class decoder selected.
255 rule - Name of the rule in ARM manual that defines
256 the decoder action.
257 pattern - The placement of 0/1's within any instruction
258 that is matched by the corresponding rule.
259 constraints - Additional constraints that apply to the rule.
260 """
261 def __init__(self, name, rule, pattern, constraints):
262 self.name = name
263 self.rule = rule
264 self.pattern = pattern
265 self.constraints = constraints
266
267 def action_filter(self, names):
268 return DecoderAction(
269 self.name if 'name' in names else None,
270 self.rule if 'rule' in names else None,
271 self.pattern if 'pattern' in names else None,
272 self.constraints if 'constraints' in names else None)
273
274 def __eq__(self, other):
275 return (other.__class__.__name__ == 'DecoderAction'
276 and self.name == other.name
277 and self.rule == other.rule
278 and self.pattern == other.pattern
279 and self.constraints == other.constraints)
280
281 def __cmp__(self, other):
282 # Order lexicographically on type/fields.
283 value = cmp(other.__class__.__name__, 'DecoderAction')
284 if value != 0: return value
285 value = cmp(self.name, other.name)
286 if value != 0: return value
287 value = cmp(self.rule, other.rule)
288 if value != 0: return value
289 value = cmp(self.pattern, other.pattern)
290 if value != 0: return value
291 return cmp(self.constraints, other.constraints)
292
293 def __hash__(self):
294 return (hash('DecoderAction') + hash(self.name) + hash(self.rule) +
295 hash(self.pattern) + hash(self.constraints))
296
297 def __repr__(self):
298 return '=%s %s %s %s' % (self.name, self.rule,
299 self.pattern, self.constraints)
300
301 class DecoderMethod(object):
302 """An action defining a parse method to call.
303
304 Corresponds to the parsed decoder method:
305 decoder_method ::= '->' id
306
307 Fields are:
308 name - The name of the corresponding table (i.e. method) that
309 should be used to continue searching for a matching class
310 decoder.
311 """
312 def __init__(self, name):
313 self.name = name
314
315 def action_filter(self, unused_names):
316 return self
317
318 def __eq__(self, other):
319 return (self.__class__.__name__ == 'DecoderMethod'
320 and self.name == other.name)
321
322 def __cmp__(self, other):
323 # Lexicographically compare types/fields.
324 value = cmp(other.__class__.__name__, 'DecoderMethod')
325 if value != 0: return value
326 return cmp(self.name, other.name)
327
328 def __hash__(self):
329 return hash('DecoderMethod') + hash(self.name)
330
331 def __repr__(self):
332 return '->%s' % self.name
231 333
232 class Row(object): 334 class Row(object):
233 """ A row in a Table.""" 335 """ A row in a Table."""
234 def __init__(self, patterns, action, arch): 336 def __init__(self, patterns, action, arch):
235 """Initializes a Row. 337 """Initializes a Row.
236 Args: 338 Args:
237 patterns: a list of BitPatterns that must match for this Row to 339 patterns: a list of BitPatterns that must match for this Row to
238 match. 340 match.
239 action: the action to be taken if this Row matches. 341 action: the action to be taken if this Row matches.
240 arch: the minimum architecture that this Row can match. 342 arch: the minimum architecture that this Row can match.
(...skipping 29 matching lines...) Expand all
270 self.action, self.arch) 372 self.action, self.arch)
271 373
272 def __cmp__(self, other): 374 def __cmp__(self, other):
273 """Compares two rows, so we can order pattern matches by specificity. 375 """Compares two rows, so we can order pattern matches by specificity.
274 """ 376 """
275 return (cmp(self.patterns, other.patterns) 377 return (cmp(self.patterns, other.patterns)
276 or cmp(self.action, other.action)) 378 or cmp(self.action, other.action))
277 379
278 def __repr__(self): 380 def __repr__(self):
279 return 'Row(%s, %s)' % (repr(self.patterns), repr(self.action)) 381 return 'Row(%s, %s)' % (repr(self.patterns), repr(self.action))
382
383 class Decoder(object):
384 """Defines a class decoder which consists of set of tables.
385
386 A decoder has a primary (i.e. start) table to parse intructions (and
387 select the proper ClassDecoder), as well as a set of additional
388 tables to complete the selection of a class decoder. Instances of
389 this class correspond to the internal representation of parsed
390 decoder tables recognized by dgen_input.py (see that file for
391 details).
392
393 Fields are:
394 primary - The entry parse table to find a class decoder.
395 tables - The (sorted) set of tables defined by a decoder.
396
397 Note: maintains restriction that tables have unique names.
398 """
399
400 def __init__(self):
401 self.primary = None
402 self._is_sorted = False
403 self._tables = []
404
405 def add(self, table):
406 """Adds the table to the set of tables. Returns true if successful.
407 """
408 if filter(lambda(t): t.name == table.name, self._tables):
409 # Table with name already defined, report error.
410 return False
411 else:
412 if not self._tables:
413 self.primary = table
414 self._tables.append(table)
415 self.is_sorted = False
416 return True
417
418 def tables(self):
419 """Returns the sorted (by table name) list of tables"""
420 if self._is_sorted: return self._tables
421 self._tables = sorted(self._tables, key=lambda(tbl): tbl.name)
422 self._is_sorted = True
423 return self._tables
424
425 def action_filter(self, names):
426 """Returns a new set of tables with actions reduced to the set of
427 field names.
428 """
429 decoder = Decoder()
430 decoder._tables = sorted([ t.action_filter(names) for t in self._tables ],
431 key=lambda(tbl): tbl.name)
432 decoder.primary = filter(
433 lambda(t): t.name == self.primary.name, self._tables)[0]
434 return decoder
435
436 def decoders(self):
437 """Returns the sorted sequence of DecoderAction's defined in the tables."""
438 decoders = set()
439 for t in self._tables:
440 for r in t.rows:
441 if r.action.__class__.__name__ == 'DecoderAction':
442 decoders.add(r.action)
443 return sorted(decoders)
444
445 def rules(self):
446 """Returns the sorted sequence of DecoderActions that define
447 the rule field.
448 """
449 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