# SVP64 ReMap field
-class SVP64RMFields(SelectableIntMapping, bits=24, fields={
- "spr": range(24),
- # SVP64 RM fields: see https://libre-soc.org/openpower/sv/svp64/
- "mmode": (0,),
- "mask": range(1, 4),
- "elwidth": range(4, 6),
- "ewsrc": range(6, 8),
- "subvl": range(8, 10),
- "extra": range(10, 19),
- "mode": range(19, 24),
- # these cover the same extra field, split into parts as EXTRA2
- "extra2": dict(enumerate([
+class SVP64RMFields(SelectableIntMapping):
+ """SVP64 RM: https://libre-soc.org/openpower/sv/svp64/"""
+ spr = range(24)
+ mmode = (0,)
+ mask = range(1, 4)
+ elwidth = range(4, 6)
+ ewsrc = range(6, 8)
+ subvl = range(8, 10)
+ extra = range(10, 19)
+ mode = range(19, 24)
+ extra2 = dict(enumerate([
range(10, 12),
range(12, 14),
range(14, 16),
range(16, 18),
- ])),
- "smask": range(16, 19),
- # and here as well, but EXTRA3
- "extra3": dict(enumerate([
+ ]))
+ smask = range(16, 19)
+ extra3 = dict(enumerate([
range(10, 13),
range(13, 16),
range(16, 19),
- ])),
-}):
+ ]))
- def __init__(self, value=0):
- super().__init__(value=value)
- self.spr = self
SVP64RM_MMODE_SIZE = len(SVP64RMFields.mmode)
SVP64RM_MODE_SIZE = len(SVP64RMFields.mode)
-# SVP64 Prefix fields: see https://libre-soc.org/openpower/sv/svp64/
-class SVP64PrefixFields(SelectableIntMapping, bits=32, fields={
- "insn": range(32),
- # 6 bit major opcode EXT001, 2 bits "identifying" (7, 9), 24 SV ReMap
- "major": range(0, 6),
- "pid": (7, 9),
- # SVP64 24-bit RM (ReMap)
- "rm": ((6, 8) + tuple(range(10, 32))),
-}):
-
- def __init__(self, value=0):
- super().__init__(value=value)
- self.insn = self
-
+class SVP64PrefixFields(SelectableIntMapping):
+ """SVP64 Prefix: https://libre-soc.org/openpower/sv/svp64/"""
+ insn = range(32)
+ major = range(0, 6)
+ pid = (7, 9)
+ rm = ((6, 8) + tuple(range(10, 32)))
SV64P_MAJOR_SIZE = len(SVP64PrefixFields.major)
SV64P_PID_SIZE = len(SVP64PrefixFields.pid)
# SVP64. first, check if the opcode is EXT001, and SVP64 id bits set
yield Settle()
opcode = yield self.dec2.dec.opcode_in
- pfx = SVP64PrefixFields() # TODO should probably use SVP64PrefixDecoder
- pfx.insn.value = opcode
+ pfx = SVP64PrefixFields(opcode)
major = pfx.major.asint(msb0=True) # MSB0 inversion
log("prefix test: opcode:", major, bin(major),
pfx.insn[7] == 0b1, pfx.insn[9] == 0b1)
return self._op(xor, b)
def __lt__(self, b):
- return self._op(lt, b)
+ vi = self.get_range()
+ return onebit(lt(vi, b))
def __eq__(self, b):
- return self._op(eq, b)
+ vi = self.get_range()
+ return onebit(eq(vi, b))
def get_range(self):
vi = SelectableInt(0, len(self.br))
class SelectableIntMappingMeta(type):
- @functools.total_ordering
- class Field(FieldSelectableInt):
- def __int__(self):
- return self.asint(msb0=True)
-
- def __lt__(self, b):
- return int(self).__lt__(b)
-
- def __eq__(self, b):
- return int(self).__eq__(b)
-
- class FieldProperty:
- def __init__(self, field):
- self.__field = field
-
- def __repr__(self):
- return self.__field.__repr__()
+ 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
- def __get__(self, instance, owner):
- if instance is None:
- return self.__field
+ length = 0
+ for (key, value) in mapping.items():
+ length = max(length, len(value))
- cls = SelectableIntMappingMeta.Field
- factory = lambda br: cls(si=instance, br=br)
- if isinstance(self.__field, dict):
- return {k:factory(br=v) for (k, v) in self.__field.items()}
- else:
- return factory(br=self.__field)
+ cls = super().__new__(metacls, name, bases, attrs)
+ cls.__length = length
+ cls.__mapping = mapping
- class BitsProperty:
- def __init__(self, bits):
- self.__bits = bits
+ return cls
- def __get__(self, instance, owner):
- if instance is None:
- return self.__bits
- return instance.bits
+ def __len__(cls):
+ return cls.__length
- def __repr__(self):
- return self.__bits.__repr__()
+ def __contains__(cls, key):
+ return cls.__mapping.__contains__(key)
- def __new__(metacls, name, bases, attrs, bits=None, fields=None):
- if fields is None:
- fields = {}
+ def __getitem__(cls, key):
+ return cls.__mapping.__getitem__(key)
- def field(item):
- (key, value) = item
- if isinstance(value, dict):
- value = dict(map(field, value.items()))
- else:
- value = tuple(value)
- return (key, value)
+ def __iter__(cls):
+ yield from cls.__mapping.items()
+ if type(cls) is not SelectableIntMappingMeta:
+ yield from super().__iter__()
- fields = dict(map(field, fields.items()))
- for (key, value) in fields.items():
- attrs.setdefault(key, metacls.FieldProperty(value))
+class SelectableIntMapping(SelectableInt, metaclass=SelectableIntMappingMeta):
+ def __init__(self, value=0, bits=None):
+ if isinstance(value, SelectableInt):
+ value = value.value
if bits is None:
- for base in bases:
- bits = getattr(base, "bits", None)
- if bits is not None:
- break
-
- if not isinstance(bits, int):
+ bits = len(self.__class__)
+ if bits != len(self.__class__):
raise ValueError(bits)
- attrs.setdefault("bits", metacls.BitsProperty(bits))
- cls = super().__new__(metacls, name, bases, attrs)
- cls.__fields = fields
- return cls
+ return super().__init__(value=value, bits=bits)
- def __iter__(cls):
- for (key, value) in cls.__fields.items():
- yield (key, value)
+ def __iter__(self):
+ for (name, _) in self.__class__:
+ yield (name, getattr(self, name))
-
-class SelectableIntMapping(SelectableInt,
- metaclass=SelectableIntMappingMeta, bits=0):
- def __init__(self, value=0, bits=None):
- if isinstance(value, int) and bits is None:
- bits = self.__class__.bits
- return super().__init__(value, bits)
+ 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):