- rv = cls.__rv.c_typedef
- args = ", ".join(arg_cls.c_var(arg_name) \
- for (arg_name, arg_cls) in cls.__args)
- return f"{prefix}{rv} {name}({args}){suffix}"
-
-
-class FieldsMappingMeta(EnumMeta):
- class HelperMeta(FunctionMeta):
- def __new__(metacls, name, bases, attrs, rv, args, enum):
- cls = super().__new__(metacls, name, bases, attrs, rv=rv, args=args)
- cls.__enum = enum
- return cls
-
- def __iter__(cls):
- short_c_tag = cls.__enum.c_tag[:-len("_field")]
- # Use __members__, not __iter__, otherwise aliases are lost.
- for (name, value) in cls.__enum.__members__.items():
- yield (f"{short_c_tag}_{name}".upper(), value)
-
- class GetterMeta(HelperMeta):
- def __new__(metacls, name, bases, attrs, enum, struct):
- return super().__new__(metacls, name, bases, attrs,
- enum=enum, rv=UInt32, args=(
- ("storage", struct),
- ("field", enum),
- ))
-
- class SetterMeta(HelperMeta):
- def __new__(metacls, name, bases, attrs, enum, struct):
- return super().__new__(metacls, name, bases, attrs, enum=enum,
- rv=Void, args=(
- ("*storage", struct),
- ("field", enum),
- ("value", UInt32),
- ))
-
- def __call__(metacls, name, base=SelectableIntMapping, **kwargs):
- def flatten(mapping, parent=""):
- for (key, value) in mapping.items():
- key = f"{parent}_{key}" if parent else key
- if isinstance(value, dict):
- yield from flatten(mapping=value, parent=key)
- else:
- value = map(lambda bit: bit, reversed(value))
- # value = map(lambda bit: ((base.bits - 1) - bit),
- # reversed(value))
- yield (key.upper(), tuple(value))
-
- tag = f"svp64_{name.lower()}"
- fields = dict(flatten(mapping=dict(base)))
- bitmap = type(name, (Bitmap,), {}, typedef="uint32_t", bits=base.bits)
- struct = _dataclasses.make_dataclass(name, (("value", bitmap),),
- bases=(Struct,), frozen=True, eq=True)
-
- cls = super().__call__(name=name, entries=fields, tag=f"{tag}_field",
- **kwargs)
-
- def c_value(fields, stmt):
- yield "switch (field) {"
- for (field_name, field_value) in fields:
- yield from indent([f"case {field_name}:"])
- yield from indent(indent(map(stmt,
- enumerate(field_value.value))))
- yield from indent(indent(["break;"]))
- yield "}"
-
- class Getter(metaclass=FieldsMappingMeta.GetterMeta,
- enum=cls, struct=struct):
- def c_value(self, prefix="", suffix=""):
- yield f"{prefix}{{"
- yield from indent([
- UInt32.c_var(name="result", suffix=" = UINT32_C(0);"),
- UInt32.c_var(name="origin", suffix=" = storage.value;"),
- ])
- yield ""
- yield from indent(c_value(fields=self.__class__,
- stmt=lambda kv: f"result |= SVP64_FIELD_GET(origin, {kv[1]}, {kv[0]});"))
- yield ""
- yield from indent(["return result;"])
- yield f"}}{suffix}"
-
- class Setter(metaclass=FieldsMappingMeta.SetterMeta,
- enum=cls, struct=struct):
- def c_value(self, prefix="", suffix=""):
- yield f"{prefix}{{"
- yield from indent([
- UInt32.c_var(name="result", suffix=" = storage->value;"),
- ])
- yield ""
- yield from indent(c_value(fields=self.__class__,
- stmt=lambda kv: f"SVP64_FIELD_SET(&result, value, {kv[0]}, {kv[1]});"))
- yield ""
- yield from indent(["storage->value = result;"])
- yield f"}}{suffix}"
-
- cls.__tag = tag
- cls.__struct = struct
- cls.__getter = Getter()
- cls.__setter = Setter()
-
- return cls
-
- @property
- def c_getter(cls):
- return cls.__getter
-
- @property
- def c_setter(cls):
- return cls.__setter