powerpc/sstep: Add tests for prefixed floating-point load/stores
authorJordan Niethe <jniethe5@gmail.com>
Mon, 25 May 2020 02:59:20 +0000 (12:59 +1000)
committerMichael Ellerman <mpe@ellerman.id.au>
Thu, 23 Jul 2020 07:25:12 +0000 (17:25 +1000)
Add tests for the prefixed versions of the floating-point load/stores
that are currently tested. This includes the following instructions:
  * Prefixed Load Floating-Point Single (plfs)
  * Prefixed Load Floating-Point Double (plfd)
  * Prefixed Store Floating-Point Single (pstfs)
  * Prefixed Store Floating-Point Double (pstfd)

Skip the new tests if ISA v3.10 is unsupported.

Signed-off-by: Jordan Niethe <jniethe5@gmail.com>
[mpe: Fix conflicts with ppc-opcode.h changes]
Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
Link: https://lore.kernel.org/r/20200525025923.19843-2-jniethe5@gmail.com
arch/powerpc/include/asm/ppc-opcode.h
arch/powerpc/lib/test_emulate_step.c

index 90ae33a..4c0bdaf 100644 (file)
 #define PPC_INST_BRANCH_COND           0x40800000
 
 /* Prefixes */
+#define PPC_INST_LFS                   0xc0000000
+#define PPC_INST_STFS                  0xd0000000
+#define PPC_INST_LFD                   0xc8000000
+#define PPC_INST_STFD                  0xd8000000
 #define PPC_PREFIX_MLS                 0x06000000
 #define PPC_PREFIX_8LS                 0x04000000
 
index 34f1ea0..0059290 100644 (file)
        ppc_inst_prefix(PPC_PREFIX_8LS | __PPC_PRFX_R(pr) | IMM_H(i), \
                        PPC_INST_PSTD | ___PPC_RT(r) | ___PPC_RA(base) | IMM_L(i))
 
+#define TEST_PLFS(r, base, i, pr) \
+       ppc_inst_prefix(PPC_PREFIX_MLS | __PPC_PRFX_R(pr) | IMM_H(i), \
+                       PPC_INST_LFS | ___PPC_RT(r) | ___PPC_RA(base) | IMM_L(i))
+
+#define TEST_PSTFS(r, base, i, pr) \
+       ppc_inst_prefix(PPC_PREFIX_MLS | __PPC_PRFX_R(pr) | IMM_H(i), \
+                       PPC_INST_STFS | ___PPC_RT(r) | ___PPC_RA(base) | IMM_L(i))
+
+#define TEST_PLFD(r, base, i, pr) \
+       ppc_inst_prefix(PPC_PREFIX_MLS | __PPC_PRFX_R(pr) | IMM_H(i), \
+                       PPC_INST_LFD | ___PPC_RT(r) | ___PPC_RA(base) | IMM_L(i))
+
+#define TEST_PSTFD(r, base, i, pr) \
+       ppc_inst_prefix(PPC_PREFIX_MLS | __PPC_PRFX_R(pr) | IMM_H(i), \
+                       PPC_INST_STFD | ___PPC_RT(r) | ___PPC_RA(base) | IMM_L(i))
+
 static void __init init_pt_regs(struct pt_regs *regs)
 {
        static unsigned long msr;
@@ -304,6 +320,53 @@ static void __init test_lfsx_stfsx(void)
                show_result("stfsx", "FAIL");
 }
 
+static void __init test_plfs_pstfs(void)
+{
+       struct pt_regs regs;
+       union {
+               float a;
+               int b;
+       } c;
+       int cached_b;
+       int stepped = -1;
+
+       if (!cpu_has_feature(CPU_FTR_ARCH_31)) {
+               show_result("pld", "SKIP (!CPU_FTR_ARCH_31)");
+               return;
+       }
+
+       init_pt_regs(&regs);
+
+
+       /*** plfs ***/
+
+       c.a = 123.45;
+       cached_b = c.b;
+
+       regs.gpr[3] = (unsigned long)&c.a;
+
+       /* plfs frt10, 0(r3), 0  */
+       stepped = emulate_step(&regs, TEST_PLFS(10, 3, 0, 0));
+
+       if (stepped == 1)
+               show_result("plfs", "PASS");
+       else
+               show_result("plfs", "FAIL");
+
+
+       /*** pstfs ***/
+
+       c.a = 678.91;
+
+       /* pstfs frs10, 0(r3), 0 */
+       stepped = emulate_step(&regs, TEST_PSTFS(10, 3, 0, 0));
+
+       if (stepped == 1 && c.b == cached_b)
+               show_result("pstfs", "PASS");
+       else
+               show_result("pstfs", "FAIL");
+}
+
 static void __init test_lfdx_stfdx(void)
 {
        struct pt_regs regs;
@@ -346,6 +409,53 @@ static void __init test_lfdx_stfdx(void)
        else
                show_result("stfdx", "FAIL");
 }
+
+static void __init test_plfd_pstfd(void)
+{
+       struct pt_regs regs;
+       union {
+               double a;
+               long b;
+       } c;
+       long cached_b;
+       int stepped = -1;
+
+       if (!cpu_has_feature(CPU_FTR_ARCH_31)) {
+               show_result("pld", "SKIP (!CPU_FTR_ARCH_31)");
+               return;
+       }
+
+       init_pt_regs(&regs);
+
+
+       /*** plfd ***/
+
+       c.a = 123456.78;
+       cached_b = c.b;
+
+       regs.gpr[3] = (unsigned long)&c.a;
+
+       /* plfd frt10, 0(r3), 0 */
+       stepped = emulate_step(&regs, TEST_PLFD(10, 3, 0, 0));
+
+       if (stepped == 1)
+               show_result("plfd", "PASS");
+       else
+               show_result("plfd", "FAIL");
+
+
+       /*** pstfd ***/
+
+       c.a = 987654.32;
+
+       /* pstfd frs10, 0(r3), 0 */
+       stepped = emulate_step(&regs, TEST_PSTFD(10, 3, 0, 0));
+
+       if (stepped == 1 && c.b == cached_b)
+               show_result("pstfd", "PASS");
+       else
+               show_result("pstfd", "FAIL");
+}
 #else
 static void __init test_lfsx_stfsx(void)
 {
@@ -353,11 +463,23 @@ static void __init test_lfsx_stfsx(void)
        show_result("stfsx", "SKIP (CONFIG_PPC_FPU is not set)");
 }
 
+static void __init test_plfs_pstfs(void)
+{
+       show_result("plfs", "SKIP (CONFIG_PPC_FPU is not set)");
+       show_result("pstfs", "SKIP (CONFIG_PPC_FPU is not set)");
+}
+
 static void __init test_lfdx_stfdx(void)
 {
        show_result("lfdx", "SKIP (CONFIG_PPC_FPU is not set)");
        show_result("stfdx", "SKIP (CONFIG_PPC_FPU is not set)");
 }
+
+static void __init test_plfd_pstfd(void)
+{
+       show_result("plfd", "SKIP (CONFIG_PPC_FPU is not set)");
+       show_result("pstfd", "SKIP (CONFIG_PPC_FPU is not set)");
+}
 #endif /* CONFIG_PPC_FPU */
 
 #ifdef CONFIG_ALTIVEC
@@ -494,7 +616,9 @@ static void __init run_tests_load_store(void)
        test_pstd();
        test_ldarx_stdcx();
        test_lfsx_stfsx();
+       test_plfs_pstfs();
        test_lfdx_stfdx();
+       test_plfd_pstfd();
        test_lvx_stvx();
        test_lxvd2x_stxvd2x();
 }