power_insn: introduce validation stubs
authorDmitry Selyutin <ghostmansd@gmail.com>
Tue, 15 Nov 2022 19:25:10 +0000 (22:25 +0300)
committerLuke Kenneth Casson Leighton <lkcl@lkcl.net>
Fri, 2 Jun 2023 18:51:16 +0000 (19:51 +0100)
src/openpower/decoder/power_insn.py

index f22536270d7c62049a310afdebe93ee58155eb54..6b94719b39aac5c6032463cea349037e16a03ac7 100644 (file)
@@ -2451,6 +2451,9 @@ class Specifier:
     def match(cls, desc, record):
         raise NotImplementedError
 
+    def validate(self, others):
+        pass
+
     def assemble(self, insn):
         raise NotImplementedError
 
@@ -2633,6 +2636,33 @@ class SpecifierDM(SpecifierMask):
         insn.prefix.rm.mask = self.pred.mask
 
 
+class Specifiers(tuple):
+    SPECS = (
+        SpecifierWidth,
+        SpecifierSubVL,
+        SpecifierFF,
+        SpecifierPR,
+        SpecifierM,
+        SpecifierSM,
+        SpecifierDM,
+    )
+
+    def __new__(cls, items, record):
+        def transform(item):
+            for spec_cls in cls.SPECS:
+                spec = spec_cls.match(item, record=record)
+                if spec is not None:
+                    return spec
+            raise ValueError(item)
+
+        specs = tuple(map(transform, items))
+        items = list(specs)
+        while items:
+            items.pop().validate(others=items)
+
+        return super().__new__(cls, specs)
+
+
 class SVP64Instruction(PrefixedInstruction):
     """SVP64 instruction: https://libre-soc.org/openpower/sv/svp64/"""
     class Prefix(PrefixedInstruction.Prefix):
@@ -2655,26 +2685,6 @@ class SVP64Instruction(PrefixedInstruction):
             bits.append(bit)
         return "".join(map(str, bits))
 
-    @classmethod
-    def specifier(cls, desc, record):
-        specifiers = (
-            SpecifierWidth,
-            SpecifierSubVL,
-            SpecifierFF,
-            SpecifierPR,
-            SpecifierMask,
-            SpecifierSM,
-            SpecifierDM,
-        )
-
-        for spec_cls in specifiers:
-            match = spec_cls.match(desc, record=record)
-            if match is not None:
-                return match
-
-        raise ValueError(desc)
-
-    @classmethod
     def assemble(cls, db, opcode, arguments=None, specifiers=None):
         if arguments is None:
             arguments = ()
@@ -2684,9 +2694,9 @@ class SVP64Instruction(PrefixedInstruction):
         record = db[opcode]
         insn = cls.integer(value=0)
 
-        specifier = lambda desc: cls.specifier(desc=desc, record=record)
-        for spec in map(specifier, specifiers):
-            spec.assemble(insn=insn)
+        specifiers = Specifiers(items=specifiers, record=record)
+        for specifier in specifiers:
+            specifier.assemble(insn=insn)
 
         for operand in record.static_operands:
             operand.assemble(insn=insn)