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

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
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
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 def __init__(self, name, rule, pattern, constraints):
251 self.name = name
robertm 2012/04/17 17:12:19 for private member fields we usually use the leadi
Karl 2012/04/17 19:28:31 These fields are intentionally public.
252 self.rule = rule
253 self.pattern = pattern
254 self.constraints = constraints
255
256 def action_filter(self, names):
257 return DecoderAction(
258 self.name if 'name' in names else None,
259 self.rule if 'rule' in names else None,
260 self.pattern if 'pattern' in names else None,
261 self.constraints if 'constraints' in names else None)
262
263 def __eq__(self, other):
264 return (other.__class__.__name__ == 'DecoderAction'
265 and self.name == other.name
266 and self.rule == other.rule
267 and self.pattern == other.pattern
268 and self.constraints == other.constraints)
269
270 def __cmp__(self, other):
271 value = cmp(other.__class__.__name__, 'DecoderAction')
robertm 2012/04/17 17:12:19 add a function comment
Karl 2012/04/17 19:28:31 Done.
272 if value != 0: return value
273 value = cmp(self.name, other.name)
274 if value != 0: return value
275 value = cmp(self.rule, other.rule)
276 if value != 0: return value
277 value = cmp(self.pattern, other.pattern)
278 if value != 0: return value
279 return cmp(self.constraints, other.constraints)
280
281 def __hash__(self):
282 return (hash('DecoderAction') + hash(self.name) + hash(self.rule) +
283 hash(self.pattern) + hash(self.constraints))
284
285 def __repr__(self):
286 return '=%s %s %s %s' % (self.name, self.rule,
287 self.pattern, self.constraints)
288
289 class DecoderMethod(object):
290 """An action defining a parse method to call."""
robertm 2012/04/17 17:12:19 maybe give example of a parse method
Karl 2012/04/17 19:28:31 Done.
291 def __init__(self, name):
292 self.name = name
293
294 def action_filter(self, unused_names):
295 return self
296
297 def __eq__(self, other):
298 return (self.__class__.__name__ == 'DecoderMethod'
299 and self.name == other.name)
300
301 def __cmp__(self, other):
302 value = cmp(other.__class__.__name__, 'DecoderMethod')
303 if value != 0: return value
304 return cmp(self.name, other.name)
305
306 def __hash__(self):
307 return hash('DecoderMethod') + hash(self.name)
308
309 def __repr__(self):
310 return '->%s' % self.name
231 311
232 class Row(object): 312 class Row(object):
233 """ A row in a Table.""" 313 """ A row in a Table."""
234 def __init__(self, patterns, action, arch): 314 def __init__(self, patterns, action, arch):
235 """Initializes a Row. 315 """Initializes a Row.
236 Args: 316 Args:
237 patterns: a list of BitPatterns that must match for this Row to 317 patterns: a list of BitPatterns that must match for this Row to
238 match. 318 match.
239 action: the action to be taken if this Row matches. 319 action: the action to be taken if this Row matches.
240 arch: the minimum architecture that this Row can match. 320 arch: the minimum architecture that this Row can match.
(...skipping 29 matching lines...) Expand all
270 self.action, self.arch) 350 self.action, self.arch)
271 351
272 def __cmp__(self, other): 352 def __cmp__(self, other):
273 """Compares two rows, so we can order pattern matches by specificity. 353 """Compares two rows, so we can order pattern matches by specificity.
274 """ 354 """
275 return (cmp(self.patterns, other.patterns) 355 return (cmp(self.patterns, other.patterns)
276 or cmp(self.action, other.action)) 356 or cmp(self.action, other.action))
277 357
278 def __repr__(self): 358 def __repr__(self):
279 return 'Row(%s, %s)' % (repr(self.patterns), repr(self.action)) 359 return 'Row(%s, %s)' % (repr(self.patterns), repr(self.action))
360
361 class Decoder(object):
362 """Defines a class decoder which consists of set of tables, with a primary
robertm 2012/04/17 17:12:19 give example of a class (it would be nice if one
Karl 2012/04/17 19:28:31 Done.
363 (i.e. start) table to parse intructions and select the proper ClassDecoder
364 to use. Note: maintains restriction that tables have unique names.
365 """
366
367 def __init__(self):
368 self.primary = None
369 self._is_sorted = False
370 self._tables = []
371
372 def add(self, table):
373 """Adds the table to the set of tables. Returns true if successful.
374 """
375 if filter(lambda(t): t.name == table.name, self._tables):
376 # Table with name already defined, report error.
377 return False
378 else:
379 if not self._tables:
380 self.primary = table
381 self._tables.append(table)
382 self.is_sorted = False
383 return True
384
385 def tables(self):
386 """Returns the sorted (by table name) list of tables"""
387 if self._is_sorted: return self._tables
388 self._tables = sorted(self._tables, key=lambda(tbl): tbl.name)
389 self._is_sorted = True
390 return self._tables
391
392 def action_filter(self, names):
393 """Returns a new set of tables with actions reduced to the set of
394 field names.
395 """
396 decoder = Decoder()
397 decoder._tables = sorted([ t.action_filter(names) for t in self._tables ],
398 key=lambda(tbl): tbl.name)
399 decoder.primary = filter(
400 lambda(t): t.name == self.primary.name, self._tables)[0]
401 return decoder
402
403 def decoders(self):
404 """Returns the sorted sequence of DecoderAction's defined in the tables."""
405 decoders = set()
406 for t in self._tables:
407 for r in t.rows:
408 if r.action.__class__.__name__ == 'DecoderAction':
409 decoders.add(r.action)
410 return sorted(decoders)
411
412 def rules(self):
413 """Returns the sorted sequence of DecoderActions that define
414 the rule field.
415 """
416 return sorted(filter(lambda (r): r.rule, self.decoders()))
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698