sv_binutils: introduce Integer class
[openpower-isa.git] / src / openpower / sv / sv_binutils.py
index cf1a36973a55e2271bf96ec2c68519d493534297..6b0a9776f682729209e5f458ca02741b9de45680 100644 (file)
@@ -32,23 +32,23 @@ def indent(strings):
     return map(lambda string: ("    " + string), strings)
 
 
-class CType:
-    @classmethod
+class CTypeMeta(type):
     @_abc.abstractmethod
-    def c_decl(self, name):
+    def c_decl(cls):
         pass
 
     @_abc.abstractmethod
-    def c_value(self, prefix="", suffix=""):
+    def c_var(cls, name):
         pass
 
-    @classmethod
+
+class CType(metaclass=CTypeMeta):
     @_abc.abstractmethod
-    def c_var(self, name):
+    def c_value(self, prefix="", suffix=""):
         pass
 
 
-class EnumMeta(_enum.EnumMeta):
+class EnumMeta(_enum.EnumMeta, CTypeMeta):
     def __call__(metacls, name, entries, tag=None, **kwargs):
         if isinstance(entries, type) and issubclass(entries, _enum.Enum):
             entries = dict(entries.__members__)
@@ -109,6 +109,64 @@ class Constant(CType, _enum.Enum, metaclass=EnumMeta):
 Mode = Constant("Mode", _SVP64MODE)
 
 
+class StructMeta(CTypeMeta):
+    def __new__(metacls, name, bases, attrs, tag=None):
+        if tag is None:
+            tag = f"svp64_{name.lower()}"
+
+        cls = super().__new__(metacls, name, bases, attrs)
+        cls.__tag = tag
+
+        return cls
+
+    @property
+    def c_tag(cls):
+        return cls.__tag
+
+    def c_decl(cls):
+        yield f"struct {cls.c_tag} {{"
+        for field in _dataclasses.fields(cls):
+            yield from indent(field.type.c_var(name=f"{field.name};"))
+        yield f"}};"
+
+    def c_var(cls, name):
+        yield f"struct {cls.c_tag} {name}"
+
+
+@_dataclasses.dataclass(eq=True, frozen=True)
+class Struct(CType, metaclass=StructMeta):
+    def c_value(self, prefix="", suffix=""):
+        yield f"{prefix}{{"
+        for field in _dataclasses.fields(self):
+            name = field.name
+            attr = getattr(self, name)
+            yield from indent(attr.c_value(prefix=f".{name} = ", suffix=","))
+        yield f"}}{suffix}"
+
+
+class IntegerMeta(CTypeMeta):
+    def __new__(metacls, name, bases, attrs, typedef=None):
+        cls = super().__new__(metacls, name, bases, attrs)
+        cls.__typedef = typedef
+
+        return cls
+
+    @property
+    def c_typedef(cls):
+        return cls.__typedef
+
+    def c_decl(cls):
+        yield "#include <stdint.h>"
+
+    def c_var(cls, name):
+        yield f"{cls.c_typedef} {name}"
+
+
+class Integer(CType, int, metaclass=IntegerMeta):
+    def c_value(self, prefix="", suffix=""):
+        yield f"{prefix}{self}{suffix}"
+
+
 class Opcode(CType):
     def __init__(self, value, mask, bits):
         self.__value = value
@@ -200,7 +258,7 @@ class Name(CType, str):
 
 
 @_dataclasses.dataclass(eq=True, frozen=True)
-class Record(CType):
+class Record(Struct):
     in1: In1Sel
     in2: In2Sel
     in3: In3Sel
@@ -231,21 +289,9 @@ class Record(CType):
             yield from indent([f"uint64_t : {bits_rsvd};"])
         yield f"}};"
 
-    def c_value(self, prefix="", suffix=""):
-        yield f"{prefix}{{"
-        for field in _dataclasses.fields(self):
-            name = field.name
-            attr = getattr(self, name)
-            yield from indent(attr.c_value(prefix=f".{name} = ", suffix=","))
-        yield f"}}{suffix}"
-
-    @classmethod
-    def c_var(cls, name):
-        yield f"struct svp64_record {name}"
-
 
 @_dataclasses.dataclass(eq=True, frozen=True)
-class Entry(CType):
+class Entry(Struct):
     name: Name
     record: Record
 
@@ -255,25 +301,6 @@ class Entry(CType):
 
         return self.name < other.name
 
-    @classmethod
-    def c_decl(cls):
-        yield f"struct svp64_entry {{"
-        for field in _dataclasses.fields(cls):
-            yield from indent(field.type.c_var(name=f"{field.name};"))
-        yield f"}};"
-
-    def c_value(self, prefix="", suffix=""):
-        yield f"{prefix}{{"
-        for field in _dataclasses.fields(self):
-            name = field.name
-            attr = getattr(self, name)
-            yield from indent(attr.c_value(prefix=f".{name} = ", suffix=","))
-        yield f"}}{suffix}"
-
-    @classmethod
-    def c_var(cls, name):
-        yield f"struct svp64_entry {name}"
-
 
 class Codegen(_enum.Enum):
     PPC_SVP64_H = _enum.auto()