generalize assemble() fn so other test cases can easily use it
authorJacob Lifshay <programmerjake@gmail.com>
Thu, 14 Sep 2023 06:22:33 +0000 (23:22 -0700)
committerJacob Lifshay <programmerjake@gmail.com>
Thu, 14 Sep 2023 06:22:33 +0000 (23:22 -0700)
src/openpower/test/algorithms/svp64_utf_8_validation.py
src/openpower/test/util.py [new file with mode: 0644]

index 054fd481dab0040dcb302f0506ab04bc8b52c864..8b7698a7f3dcc9546c72fd1bfb5f75b3bfc305a2 100644 (file)
@@ -2,12 +2,9 @@
 # Copyright 2022 Jacob Lifshay
 
 import enum
-import re
-from openpower.decoder.selectable_int import SelectableInt
-from openpower.simulator.program import Program
 from openpower.test.common import TestAccumulatorBase, skip_case
+from openpower.test.util import assemble
 from openpower.test.state import ExpectedState
-from openpower.insndb.asm import SVP64Asm
 from cached_property import cached_property
 
 
@@ -285,47 +282,6 @@ def svp64_utf8_validation_asm():
     ]
 
 
-def assemble(instructions, start_pc=0):
-    pc = start_pc
-    labels = {}
-    out_instructions = []
-    for instr in instructions:
-        m = re.fullmatch(r" *([a-zA-Z0-9_]+): *(#.*)?", instr)
-        if m is not None:
-            name = m.group(1)
-            if name in labels:
-                raise ValueError(f"label {name!r} defined multiple times")
-            labels[name] = pc
-            continue
-        m = re.fullmatch(r" *sv\.[a-zA-Z0-9_].*", instr)
-        if m is not None:
-            pc += 8
-        else:
-            pc += 4
-        out_instructions.append((pc, instr))
-    last_pc = pc
-
-    for (idx, (pc, instr)) in enumerate(tuple(out_instructions)):
-        for (label, target) in labels.items():
-            if label in instr:
-                if pc < target:
-                    sign = ""
-                    addr = (target - pc + 4)
-                else:
-                    sign = "-"
-                    addr = (pc - target - 4)
-
-                origin = instr
-                instr = instr.replace(label, f"{sign}0x{addr:X}")
-                break
-        out_instructions[idx] = instr
-
-    for k, v in labels.items():
-        out_instructions.append(f".set {k}, . - 0x{last_pc - v:X} # 0x{v:X}")
-
-    return Program(list(SVP64Asm(out_instructions)), 0)
-
-
 class SVP64UTF8ValidationTestCase(TestAccumulatorBase):
     def __init__(self):
         self.__seen_cases = set()
diff --git a/src/openpower/test/util.py b/src/openpower/test/util.py
new file mode 100644 (file)
index 0000000..8824355
--- /dev/null
@@ -0,0 +1,53 @@
+import re
+from openpower.insndb.asm import SVP64Asm
+from openpower.simulator.program import Program
+from functools import lru_cache
+
+
+def assemble(instructions, start_pc=0, bigendian=False):
+    """ assemble `instructions`, handling labels.
+        returns a Program instance
+    """
+    return __cached_assemble(tuple(instructions), start_pc, bigendian)
+
+
+@lru_cache(maxsize=10000)
+def __cached_assemble(instructions, start_pc, bigendian):
+    pc = start_pc
+    labels = {}
+    out_instructions = []
+    for instr in instructions:
+        m = re.fullmatch(r" *([a-zA-Z0-9_]+): *(#.*)?", instr)
+        if m is not None:
+            name = m.group(1)
+            if name in labels:
+                raise ValueError(f"label {name!r} defined multiple times")
+            labels[name] = pc
+            continue
+        m = re.fullmatch(r" *sv\.[a-zA-Z0-9_].*", instr)
+        if m is not None:
+            pc += 8
+        else:
+            pc += 4
+        out_instructions.append((pc, instr))
+    last_pc = pc
+
+    for (idx, (pc, instr)) in enumerate(tuple(out_instructions)):
+        for (label, target) in labels.items():
+            if label in instr:
+                if pc < target:
+                    sign = ""
+                    addr = (target - pc + 4)
+                else:
+                    sign = "-"
+                    addr = (pc - target - 4)
+
+                origin = instr
+                instr = instr.replace(label, f"{sign}0x{addr:X}")
+                break
+        out_instructions[idx] = instr
+
+    for k, v in labels.items():
+        out_instructions.append(f".set {k}, . - 0x{last_pc - v:X} # 0x{v:X}")
+
+    return Program(list(SVP64Asm(out_instructions)), bigendian)