selftests/powerpc: Add matrix multiply assist (MMA) test
authorAlistair Popple <alistair@popple.id.au>
Mon, 22 Jun 2020 02:18:32 +0000 (12:18 +1000)
committerMichael Ellerman <mpe@ellerman.id.au>
Wed, 27 Apr 2022 06:32:42 +0000 (16:32 +1000)
Adds a simple test of some basic matrix multiply assist (MMA)
instructions.

Signed-off-by: Alistair Popple <alistair@popple.id.au>
Tested-by: Joel Stanley <joel@jms.id.au>
Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
Link: https://lore.kernel.org/r/20200622021832.15870-1-alistair@popple.id.au
tools/testing/selftests/powerpc/include/utils.h
tools/testing/selftests/powerpc/math/Makefile
tools/testing/selftests/powerpc/math/mma.S [new file with mode: 0644]
tools/testing/selftests/powerpc/math/mma.c [new file with mode: 0644]

index b7d188fc87c745fb856e1ecdcc9faec2c364c2d7..b9fa9cd709df4c5ec4fc509cd0a3808250b39f55 100644 (file)
@@ -135,6 +135,11 @@ do {                                                               \
 #define PPC_FEATURE2_ARCH_3_1 0x00040000
 #endif
 
+/* POWER10 features */
+#ifndef PPC_FEATURE2_MMA
+#define PPC_FEATURE2_MMA 0x00020000
+#endif
+
 #if defined(__powerpc64__)
 #define UCONTEXT_NIA(UC)       (UC)->uc_mcontext.gp_regs[PT_NIP]
 #define UCONTEXT_MSR(UC)       (UC)->uc_mcontext.gp_regs[PT_MSR]
index fcc91c2059841f360fd60563832553a9ec2c6e39..3948f7c510aa7470edcaceda13cc397f415f3310 100644 (file)
@@ -1,5 +1,5 @@
 # SPDX-License-Identifier: GPL-2.0
-TEST_GEN_PROGS := fpu_syscall fpu_preempt fpu_signal fpu_denormal vmx_syscall vmx_preempt vmx_signal vsx_preempt
+TEST_GEN_PROGS := fpu_syscall fpu_preempt fpu_signal fpu_denormal vmx_syscall vmx_preempt vmx_signal vsx_preempt mma
 
 top_srcdir = ../../../../..
 include ../../lib.mk
@@ -17,3 +17,5 @@ $(OUTPUT)/vmx_signal: vmx_asm.S ../utils.c
 
 $(OUTPUT)/vsx_preempt: CFLAGS += -mvsx
 $(OUTPUT)/vsx_preempt: vsx_asm.S ../utils.c
+
+$(OUTPUT)/mma: mma.c mma.S ../utils.c
diff --git a/tools/testing/selftests/powerpc/math/mma.S b/tools/testing/selftests/powerpc/math/mma.S
new file mode 100644 (file)
index 0000000..8528c98
--- /dev/null
@@ -0,0 +1,33 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later
+ *
+ * Test basic matrix multiply assist (MMA) functionality if available.
+ *
+ * Copyright 2020, Alistair Popple, IBM Corp.
+ */
+       .global test_mma
+test_mma:
+       /* Load accumulator via VSX registers from image passed in r3 */
+       lxvh8x  4,0,3
+       lxvh8x  5,0,4
+
+       /* Clear and prime the accumulator (xxsetaccz) */
+       .long   0x7c030162
+
+       /* Prime the accumulator with MMA VSX move to accumulator
+       * X-form (xxmtacc) (not needed due to above zeroing) */
+       //.long 0x7c010162
+
+       /* xvi16ger2s */
+       .long   0xec042958
+
+       /* Store result in image passed in r5 */
+       stxvw4x 0,0,5
+       addi    5,5,16
+       stxvw4x 1,0,5
+       addi    5,5,16
+       stxvw4x 2,0,5
+       addi    5,5,16
+       stxvw4x 3,0,5
+       addi    5,5,16
+
+       blr
diff --git a/tools/testing/selftests/powerpc/math/mma.c b/tools/testing/selftests/powerpc/math/mma.c
new file mode 100644 (file)
index 0000000..3a71808
--- /dev/null
@@ -0,0 +1,48 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Test basic matrix multiply assist (MMA) functionality if available.
+ *
+ * Copyright 2020, Alistair Popple, IBM Corp.
+ */
+#include <stdio.h>
+#include <stdint.h>
+
+#include "utils.h"
+
+extern void test_mma(uint16_t (*)[8], uint16_t (*)[8], uint32_t (*)[4*4]);
+
+static int mma(void)
+{
+       int i;
+       int rc = 0;
+       uint16_t x[] = {1, 0, 2, 0, 3, 0, 4, 0};
+       uint16_t y[] = {1, 0, 2, 0, 3, 0, 4, 0};
+       uint32_t z[4*4];
+       uint32_t exp[4*4] = {1, 2, 3, 4,
+                            2, 4, 6, 8,
+                            3, 6, 9, 12,
+                            4, 8, 12, 16};
+
+       SKIP_IF_MSG(!have_hwcap2(PPC_FEATURE2_ARCH_3_1), "Need ISAv3.1");
+       SKIP_IF_MSG(!have_hwcap2(PPC_FEATURE2_MMA), "Need MMA");
+
+       test_mma(&x, &y, &z);
+
+       for (i = 0; i < 16; i++) {
+               printf("MMA[%d] = %d ", i, z[i]);
+
+               if (z[i] == exp[i]) {
+                       printf(" (Correct)\n");
+               } else {
+                       printf(" (Incorrect)\n");
+                       rc = 1;
+               }
+       }
+
+       return rc;
+}
+
+int main(int argc, char *argv[])
+{
+       return test_harness(mma, "mma");
+}