openpower/test/bigint/mul_remap.py: add WIP mul_remap.py
authorJacob Lifshay <programmerjake@gmail.com>
Wed, 10 Jan 2024 09:16:52 +0000 (01:16 -0800)
committerJacob Lifshay <programmerjake@gmail.com>
Wed, 10 Jan 2024 09:21:19 +0000 (01:21 -0800)
src/openpower/test/bigint/mul_remap.py [new file with mode: 0644]

diff --git a/src/openpower/test/bigint/mul_remap.py b/src/openpower/test/bigint/mul_remap.py
new file mode 100644 (file)
index 0000000..2f59f25
--- /dev/null
@@ -0,0 +1,92 @@
+# SPDX-License-Identifier: LGPL-3-or-later
+# Copyright 2024 Jacob Lifshay programmerjake@gmail.com
+
+# Funded by NLnet Assure Programme 2021-02-052, https://nlnet.nl/assure part
+# of Horizon 2020 EU Programme 957073.
+#
+# * https://bugs.libre-soc.org/show_bug.cgi?id=1155
+
+""" bigint O(n^2) mul remap
+
+related bugs:
+
+ * https://bugs.libre-soc.org/show_bug.cgi?id=1155
+"""
+
+from openpower.decoder.isa.svshape import SVSHAPE
+from openpower.test.common import TestAccumulatorBase, skip_case
+from openpower.test.state import ExpectedState
+from openpower.test.util import assemble
+from nmutil.sim_util import hash_256
+from openpower.decoder.power_enums import SPRfull
+
+
+def load_u32(reg, value):
+    value = int(value)  # convert any SelectableInts to int
+    assert 0 <= value < 2 ** 32
+    if value < 2 ** 15:
+        return ["addi %d, 0, 0x%x" % (reg, value)]
+    if value < 2 ** 16:
+        return [
+            "addi %d, 0, 0" % (reg,),
+            "ori %d, %d, 0x%x" % (reg, reg, value),
+        ]
+    retval = ["addis %d, 0, 0x%x" % (reg, value >> 16)]
+    if value % 2 ** 16 != 0:
+        retval.append("ori %d, %d, 0x%x" % (reg, reg, value % 2 ** 16))
+    if value >= 2 ** 31:
+        retval.append(
+            "rldicl %d, %d, 0, 32 # clrldi %d, %d, 32" % (reg, reg, reg, reg))
+    return retval
+
+
+def mul_remap_256_x_256_to_512_asm():
+    # manually create SVSHAPE until we have svshape[34] instructions working
+    # FIXME: fill in correct SVSHAPE[0-2] values
+    # x for y in range(4) for x in range(4)
+    SVSHAPE0 = SVSHAPE(0)
+
+    # y for y in range(4) for x in range(4)
+    SVSHAPE1 = SVSHAPE(0)
+
+    # x + y for y in range(4) for x in range(4)
+    # *must not* be limited mod 4, maximum value is 6 (3 + 3)
+    SVSHAPE2 = SVSHAPE(0)
+
+    # 0 for y in range(4) for x in range(4)
+    # yes, this is a constant
+    SVSHAPE3 = SVSHAPE(0)
+    retval = [
+        "mul_256_to_512:",
+        # a is in r4-7, b is in r8-11, output (y) in r4-11
+        # matches ABI of powmod.MUL_256_X_256_TO_512_ASM
+        "setvl 0, 0, 8, 0, 1, 1",  # set VL to 8
+        "sv.or *32, *4, *4",  # move args to r32-39
+        # a is now in r32-35, b is in r36-39, y is in r4-11
+        "sv.addi *4, 0, 0",  # clear output
+        "addi 0, 0, 16",
+        "mtspr %d, 0 # mtctr 0" % (SPRfull.CTR.value,),
+        "setvl 0, 0, 16, 0, 1, 1",  # set VL to 16 (4 * 4)
+        "addic 0, 0, 0",  # clear CA
+        *load_u32(0, SVSHAPE0),
+        "mtspr %d, 0" % (SPRfull.SVSHAPE0.value,),
+        *load_u32(0, SVSHAPE1),
+        "mtspr %d, 0" % (SPRfull.SVSHAPE1.value,),
+        *load_u32(0, SVSHAPE2),
+        "mtspr %d, 0" % (SPRfull.SVSHAPE2.value,),
+    ]
+    retval += [
+        "loop:",
+        # FIXME: use SVSHAPE0 for RA, SVSHAPE1 for RB,
+        # SVSHAPE2 for RC/RT, SVSHAPE3 for RS
+        "sv.maddedu *4, *32, *36, *4",  # RS is scalar by using constant remap
+        # FIXME: use SVSHAPE2 for RT/RA
+        "sv.adde *5, *5, 20",  # FIXME: maddedu's RS is in r20, right?
+        "svstep 0, 0, 1",
+        "bc 16, 0, loop # bdnz loop",
+        "bclr 20, 0, 0 # blr",
+    ]
+    return retval
+
+
+# TODO: add test cases class, copy powmod.py's mul tests.