From 0afb441f6e707cb472c882e35a12089fb0b5df06 Mon Sep 17 00:00:00 2001 From: Luke Kenneth Casson Leighton Date: Sat, 4 Apr 2020 14:45:19 +0100 Subject: [PATCH] add OrderedSet, needed to preserve function arg order --- src/soc/decoder/orderedset.py | 51 ++++++++++++++++++++++++++++++ src/soc/decoder/pseudo/parser.py | 7 ++-- src/soc/decoder/pseudo/pywriter.py | 7 ++-- 3 files changed, 60 insertions(+), 5 deletions(-) create mode 100644 src/soc/decoder/orderedset.py diff --git a/src/soc/decoder/orderedset.py b/src/soc/decoder/orderedset.py new file mode 100644 index 00000000..d5f0b411 --- /dev/null +++ b/src/soc/decoder/orderedset.py @@ -0,0 +1,51 @@ +# Originally from http://code.activestate.com/recipes/576694/ +# cut down to minimum + +import collections + +class OrderedSet(collections.MutableSet): + + def __init__(self, iterable=None): + self.end = end = [] + end += [None, end, end] # sentinel node for doubly linked list + self.map = {} # key --> [key, prev, next] + if iterable is not None: + self |= iterable + + def __len__(self): + return len(self.map) + + def __contains__(self, key): + return key in self.map + + def add(self, key): + if key in self.map: + return + end = self.end + curr = end[1] + curr[2] = end[1] = self.map[key] = [key, curr, end] + + def discard(self, key): + if key in self.map: + key, prev, next = self.map.pop(key) + prev[2] = next + next[1] = prev + + def __iter__(self): + end = self.end + curr = end[2] + while curr is not end: + yield curr[0] + curr = curr[2] + + def __repr__(self): + if not self: + return '%s()' % (self.__class__.__name__,) + return '%s(%r)' % (self.__class__.__name__, list(self)) + +if __name__ == '__main__': + s = OrderedSet('abracadaba') + t = OrderedSet('simsalabim') + print(s | t) + print(s & t) + print(s - t) diff --git a/src/soc/decoder/pseudo/parser.py b/src/soc/decoder/pseudo/parser.py index 8b38c802..d72fc297 100644 --- a/src/soc/decoder/pseudo/parser.py +++ b/src/soc/decoder/pseudo/parser.py @@ -14,6 +14,7 @@ import astor from soc.decoder.power_decoder import create_pdecode from soc.decoder.pseudo.lexer import IndentLexer +from soc.decoder.orderedset import OrderedSet # I use the Python AST #from compiler import ast @@ -197,9 +198,9 @@ class PowerParser: self.gprs = {} for rname in ['RA', 'RB', 'RC', 'RT', 'RS']: self.gprs[rname] = None - self.read_regs = set() - self.uninit_regs = set() - self.write_regs = set() + self.read_regs = OrderedSet() + self.uninit_regs = OrderedSet() + self.write_regs = OrderedSet() # The grammar comments come from Python's Grammar/Grammar file diff --git a/src/soc/decoder/pseudo/pywriter.py b/src/soc/decoder/pseudo/pywriter.py index 6198dcd3..ddc4dc59 100644 --- a/src/soc/decoder/pseudo/pywriter.py +++ b/src/soc/decoder/pseudo/pywriter.py @@ -3,6 +3,7 @@ import os from soc.decoder.pseudo.pagereader import ISA from soc.decoder.power_pseudo import convert_to_python +from soc.decoder.orderedset import OrderedSet def get_isasrc_dir(): fdir = os.path.abspath(os.path.dirname(__file__)) @@ -10,7 +11,7 @@ def get_isasrc_dir(): return os.path.join(fdir, "isa") def create_args(reglist, extra=None): - args = set() + args = OrderedSet() for reg in reglist: args.add(reg) args = list(args) @@ -18,6 +19,7 @@ def create_args(reglist, extra=None): args = [extra] + args return ', '.join(args) + header = """\ # auto-generated by pywriter.py, do not edit or commit @@ -25,6 +27,7 @@ from soc.decoder.isa import ISACaller from soc.decoder.helpers import (EXTS64, EXTZ64, ROTL64, ROTL32, MASK,) from soc.decoder.selectable_int import SelectableInt from soc.decoder.selectable_int import selectconcat as concat +from soc.decoder.orderedset import OrderedSet class %s(ISACaller): @@ -66,7 +69,7 @@ class PyISAWriter(ISA): else: f.write("\n") # accumulate the instruction info - iinfo = "(%s, %s, %s, %s)" % \ + iinfo = "(%s, %s,\n %s, %s)" % \ (op_fname, rused['read_regs'], rused['uninit_regs'], rused['write_regs']) iinf += " instrs['%s'] = %s\n" % (page, iinfo) -- 2.30.2