power_insn: remove the whitespaces properly
[openpower-isa.git] / src / openpower / decoder / selectable_int.py
index 22fb8311cef15eed2b76f88f2c6b09893552fd68..55f5e6c824a8cb8ce52d56403897972e3c34f3b8 100644 (file)
@@ -2,7 +2,7 @@ import unittest
 import struct
 from copy import copy
 import functools
-from openpower.decoder.power_fields import BitRange
+from collections import OrderedDict
 from operator import (add, sub, mul, floordiv, truediv, mod, or_, and_, xor,
                       neg, inv, lshift, rshift, lt, eq)
 from openpower.util import log
@@ -18,6 +18,17 @@ def check_extsign(a, b):
     return SelectableInt(b.value, a.bits)
 
 
+class BitRange(OrderedDict):
+    """BitRange: remaps from straight indices (0,1,2..) to bit numbers
+    """
+
+    def __getitem__(self, subscript):
+        if isinstance(subscript, slice):
+            return list(self.values())[subscript]
+        else:
+            return OrderedDict.__getitem__(self, subscript)
+
+
 @functools.total_ordering
 class FieldSelectableInt:
     """FieldSelectableInt: allows bit-range selection onto another target
@@ -86,6 +97,8 @@ class FieldSelectableInt:
             return selectconcat(*[self.si[x] for x in key])
         elif isinstance(key, (tuple, list, range)):
             return FieldSelectableInt(si=self, br=key)
+        else:
+            raise ValueError(key)
 
     def __setitem__(self, key, value):
         if isinstance(key, SelectableInt):
@@ -100,7 +113,7 @@ class FieldSelectableInt:
                 self.si[k] = value[i]
 
     def __negate__(self):
-        return self._op1(negate)
+        return self._op1(neg)
 
     def __invert__(self):
         return self._op1(inv)
@@ -159,6 +172,9 @@ class FieldSelectableInt:
                 return True
         return False
 
+    def __int__(self):
+        return self.asint(msb0=True)
+
     def asint(self, msb0=False):
         res = 0
         brlen = len(self.br)
@@ -368,6 +384,14 @@ class SelectableInt:
             value = (self.value >> start) & mask
             log("getitem", stop, start, self.bits, hex(self.value), value)
             return SelectableInt(value, bits)
+        else:
+            bits = []
+            key = tuple(key)
+            for bit in key:
+                if not isinstance(bit, (int, SelectableInt)):
+                    raise ValueError(key)
+                bits.append(self[bit])
+            return selectconcat(*bits)
 
     def __setitem__(self, key, value):
         if isinstance(key, SelectableInt):
@@ -409,6 +433,8 @@ class SelectableInt:
             mask = ((1 << bits) - 1) << start
             value = value << start
             self.value = (self.value & ~mask) | (value & mask)
+        else:
+            raise ValueError(key)
 
     def __ge__(self, other):
         if isinstance(other, FieldSelectableInt):
@@ -500,106 +526,6 @@ class SelectableInt:
         return struct.unpack('<d', data)[0]
 
 
-class SelectableIntMappingMeta(type):
-    class Field(tuple):
-        def __call__(self, si):
-            return FieldSelectableInt(si=si, br=self)
-
-    class FieldMapping(dict):
-        def __init__(self, items):
-            if isinstance(items, dict):
-                items = items.items()
-
-            length = 0
-            mapping = {}
-            Field = SelectableIntMappingMeta.Field
-            for (key, value) in items:
-                field = Field(value)
-                mapping[key] = field
-                length = max(length, len(field))
-
-            self.__length = length
-
-            return super().__init__(mapping)
-
-        def __iter__(self):
-            yield from self.items()
-
-        def __len__(self):
-            return self.__length
-
-        def __call__(self, si):
-            return {key:value(si=si) for (key, value) in self}
-
-    def __new__(metacls, name, bases, attrs):
-        mapping = {}
-        valid = False
-        for base in reversed(bases):
-            if issubclass(base.__class__, metacls):
-                mapping.update(base)
-            if not valid and issubclass(base, SelectableInt):
-                valid = True
-        if not valid:
-            raise ValueError(bases)
-
-        for (key, value) in tuple(attrs.items()):
-            if key.startswith("_"):
-                continue
-            if isinstance(value, dict):
-                value = metacls.FieldMapping(value)
-            elif isinstance(value, (list, tuple, range)):
-                value = metacls.Field(value)
-            else:
-                continue
-            mapping[key] = value
-            attrs[key] = value
-
-        length = 0
-        for (key, value) in mapping.items():
-            length = max(length, len(value))
-
-        cls = super().__new__(metacls, name, bases, attrs)
-        cls.__length = length
-        cls.__mapping = mapping
-
-        return cls
-
-    def __len__(cls):
-        return cls.__length
-
-    def __contains__(cls, key):
-        return cls.__mapping.__contains__(key)
-
-    def __getitem__(cls, key):
-        return cls.__mapping.__getitem__(key)
-
-    def __iter__(cls):
-        yield from cls.__mapping.items()
-        if type(cls) is not SelectableIntMappingMeta:
-            yield from super().__iter__()
-
-
-class SelectableIntMapping(SelectableInt, metaclass=SelectableIntMappingMeta):
-    def __init__(self, value=0, bits=None):
-        if isinstance(value, SelectableInt):
-            value = value.value
-        if bits is None:
-            bits = len(self.__class__)
-        if bits != len(self.__class__):
-            raise ValueError(bits)
-
-        return super().__init__(value=value, bits=bits)
-
-    def __iter__(self):
-        for (name, _) in self.__class__:
-            yield (name, getattr(self, name))
-
-    def __getattribute__(self, attr):
-        if (attr != "__class__") and (attr in self.__class__):
-            return self.__class__[attr](si=self)
-        return super().__getattribute__(attr)
-
-
 def onebit(bit):
     return SelectableInt(1 if bit else 0, 1)