--- /dev/null
+# 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.