power_insn: decouple assemble routine
authorDmitry Selyutin <ghostmansd@gmail.com>
Wed, 10 May 2023 17:47:14 +0000 (17:47 +0000)
committerDmitry Selyutin <ghostmansd@gmail.com>
Sat, 13 May 2023 18:37:22 +0000 (18:37 +0000)
src/openpower/decoder/power_insn.py

index b9d92508a7654fd563e42c5b0392986b89002902..f8188edaf63c737b693a6461c6b8e6a8e1429498 100644 (file)
@@ -3635,6 +3635,10 @@ class SVP64Database:
         return None
 
 
+class AssemblerError(Exception):
+    pass
+
+
 class Database:
     def __init__(self, root):
         root = _pathlib.Path(root)
@@ -3700,3 +3704,48 @@ class Database:
             return self.__names.get(key)
 
         raise ValueError("instruction or name expected")
+
+    def assemble(self, insn, macros=None):
+        def subst(argument):
+            again = True
+            while again:
+                again = False
+                argument = _re.sub(r"\s", "", argument)
+                for (macro, value) in macros.items():
+                    if argument == macro:
+                        again = True
+                        argument = value
+                    elif argument == f"{macro}.s":
+                        again = True
+                        argument = f"{value}.s"
+                    elif argument == f"{macro}.v":
+                        again = True
+                        argument = f"{value}.v"
+                    elif argument == f"*{macro}":
+                        again = True
+                        argument = f"*{value}"
+                    elif argument == f"({macro})":
+                        again = True
+                        argument = f"({value})"
+            return argument
+
+        if macros is None:
+            macros = {}
+
+        (opcode, *arguments) = map(str.strip, _re.split(r"\s", insn))
+        arguments = _re.split(r",", "".join(arguments))
+        arguments = tuple(filter(bool, map(subst, arguments)))
+        record = self[opcode]
+        if record is not None:
+            return WordInstruction.assemble(record=record, arguments=arguments)
+
+        if opcode.startswith("sv."):
+            (opcode, *specifiers) = map(str.strip, opcode.split("/"))
+            specifiers = tuple(filter(bool, specifiers))
+            opcode = opcode[3:]
+            record = self[opcode]
+            if record is not None:
+                return SVP64Instruction.assemble(record=record,
+                    arguments=arguments, specifiers=specifiers)
+
+        raise AssemblerError(opcode)