Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-or-later
0002 /*
0003  * Simple sanity tests for instruction emulation infrastructure.
0004  *
0005  * Copyright IBM Corp. 2016
0006  */
0007 
0008 #define pr_fmt(fmt) "emulate_step_test: " fmt
0009 
0010 #include <linux/ptrace.h>
0011 #include <asm/cpu_has_feature.h>
0012 #include <asm/sstep.h>
0013 #include <asm/ppc-opcode.h>
0014 #include <asm/code-patching.h>
0015 #include <asm/inst.h>
0016 
0017 #define MAX_SUBTESTS    16
0018 
0019 #define IGNORE_GPR(n)   (0x1UL << (n))
0020 #define IGNORE_XER  (0x1UL << 32)
0021 #define IGNORE_CCR  (0x1UL << 33)
0022 #define NEGATIVE_TEST   (0x1UL << 63)
0023 
0024 #define TEST_PLD(r, base, i, pr) \
0025     ppc_inst_prefix(PPC_PREFIX_8LS | __PPC_PRFX_R(pr) | IMM_H(i), \
0026             PPC_INST_PLD | ___PPC_RT(r) | ___PPC_RA(base) | IMM_L(i))
0027 
0028 #define TEST_PLWZ(r, base, i, pr) \
0029     ppc_inst_prefix(PPC_PREFIX_MLS | __PPC_PRFX_R(pr) | IMM_H(i), \
0030             PPC_RAW_LWZ(r, base, i))
0031 
0032 #define TEST_PSTD(r, base, i, pr) \
0033     ppc_inst_prefix(PPC_PREFIX_8LS | __PPC_PRFX_R(pr) | IMM_H(i), \
0034             PPC_INST_PSTD | ___PPC_RT(r) | ___PPC_RA(base) | IMM_L(i))
0035 
0036 #define TEST_PLFS(r, base, i, pr) \
0037     ppc_inst_prefix(PPC_PREFIX_MLS | __PPC_PRFX_R(pr) | IMM_H(i), \
0038             PPC_INST_LFS | ___PPC_RT(r) | ___PPC_RA(base) | IMM_L(i))
0039 
0040 #define TEST_PSTFS(r, base, i, pr) \
0041     ppc_inst_prefix(PPC_PREFIX_MLS | __PPC_PRFX_R(pr) | IMM_H(i), \
0042             PPC_INST_STFS | ___PPC_RT(r) | ___PPC_RA(base) | IMM_L(i))
0043 
0044 #define TEST_PLFD(r, base, i, pr) \
0045     ppc_inst_prefix(PPC_PREFIX_MLS | __PPC_PRFX_R(pr) | IMM_H(i), \
0046             PPC_INST_LFD | ___PPC_RT(r) | ___PPC_RA(base) | IMM_L(i))
0047 
0048 #define TEST_PSTFD(r, base, i, pr) \
0049     ppc_inst_prefix(PPC_PREFIX_MLS | __PPC_PRFX_R(pr) | IMM_H(i), \
0050             PPC_INST_STFD | ___PPC_RT(r) | ___PPC_RA(base) | IMM_L(i))
0051 
0052 #define TEST_PADDI(t, a, i, pr) \
0053     ppc_inst_prefix(PPC_PREFIX_MLS | __PPC_PRFX_R(pr) | IMM_H(i), \
0054             PPC_RAW_ADDI(t, a, i))
0055 
0056 static void __init init_pt_regs(struct pt_regs *regs)
0057 {
0058     static unsigned long msr;
0059     static bool msr_cached;
0060 
0061     memset(regs, 0, sizeof(struct pt_regs));
0062 
0063     if (likely(msr_cached)) {
0064         regs->msr = msr;
0065         return;
0066     }
0067 
0068     asm volatile("mfmsr %0" : "=r"(regs->msr));
0069 
0070     regs->msr |= MSR_FP;
0071     regs->msr |= MSR_VEC;
0072     regs->msr |= MSR_VSX;
0073 
0074     msr = regs->msr;
0075     msr_cached = true;
0076 }
0077 
0078 static void __init show_result(char *mnemonic, char *result)
0079 {
0080     pr_info("%-14s : %s\n", mnemonic, result);
0081 }
0082 
0083 static void __init show_result_with_descr(char *mnemonic, char *descr,
0084                       char *result)
0085 {
0086     pr_info("%-14s : %-50s %s\n", mnemonic, descr, result);
0087 }
0088 
0089 static void __init test_ld(void)
0090 {
0091     struct pt_regs regs;
0092     unsigned long a = 0x23;
0093     int stepped = -1;
0094 
0095     init_pt_regs(&regs);
0096     regs.gpr[3] = (unsigned long) &a;
0097 
0098     /* ld r5, 0(r3) */
0099     stepped = emulate_step(&regs, ppc_inst(PPC_RAW_LD(5, 3, 0)));
0100 
0101     if (stepped == 1 && regs.gpr[5] == a)
0102         show_result("ld", "PASS");
0103     else
0104         show_result("ld", "FAIL");
0105 }
0106 
0107 static void __init test_pld(void)
0108 {
0109     struct pt_regs regs;
0110     unsigned long a = 0x23;
0111     int stepped = -1;
0112 
0113     if (!cpu_has_feature(CPU_FTR_ARCH_31)) {
0114         show_result("pld", "SKIP (!CPU_FTR_ARCH_31)");
0115         return;
0116     }
0117 
0118     init_pt_regs(&regs);
0119     regs.gpr[3] = (unsigned long)&a;
0120 
0121     /* pld r5, 0(r3), 0 */
0122     stepped = emulate_step(&regs, TEST_PLD(5, 3, 0, 0));
0123 
0124     if (stepped == 1 && regs.gpr[5] == a)
0125         show_result("pld", "PASS");
0126     else
0127         show_result("pld", "FAIL");
0128 }
0129 
0130 static void __init test_lwz(void)
0131 {
0132     struct pt_regs regs;
0133     unsigned int a = 0x4545;
0134     int stepped = -1;
0135 
0136     init_pt_regs(&regs);
0137     regs.gpr[3] = (unsigned long) &a;
0138 
0139     /* lwz r5, 0(r3) */
0140     stepped = emulate_step(&regs, ppc_inst(PPC_RAW_LWZ(5, 3, 0)));
0141 
0142     if (stepped == 1 && regs.gpr[5] == a)
0143         show_result("lwz", "PASS");
0144     else
0145         show_result("lwz", "FAIL");
0146 }
0147 
0148 static void __init test_plwz(void)
0149 {
0150     struct pt_regs regs;
0151     unsigned int a = 0x4545;
0152     int stepped = -1;
0153 
0154     if (!cpu_has_feature(CPU_FTR_ARCH_31)) {
0155         show_result("plwz", "SKIP (!CPU_FTR_ARCH_31)");
0156         return;
0157     }
0158 
0159     init_pt_regs(&regs);
0160     regs.gpr[3] = (unsigned long)&a;
0161 
0162     /* plwz r5, 0(r3), 0 */
0163 
0164     stepped = emulate_step(&regs, TEST_PLWZ(5, 3, 0, 0));
0165 
0166     if (stepped == 1 && regs.gpr[5] == a)
0167         show_result("plwz", "PASS");
0168     else
0169         show_result("plwz", "FAIL");
0170 }
0171 
0172 static void __init test_lwzx(void)
0173 {
0174     struct pt_regs regs;
0175     unsigned int a[3] = {0x0, 0x0, 0x1234};
0176     int stepped = -1;
0177 
0178     init_pt_regs(&regs);
0179     regs.gpr[3] = (unsigned long) a;
0180     regs.gpr[4] = 8;
0181     regs.gpr[5] = 0x8765;
0182 
0183     /* lwzx r5, r3, r4 */
0184     stepped = emulate_step(&regs, ppc_inst(PPC_RAW_LWZX(5, 3, 4)));
0185     if (stepped == 1 && regs.gpr[5] == a[2])
0186         show_result("lwzx", "PASS");
0187     else
0188         show_result("lwzx", "FAIL");
0189 }
0190 
0191 static void __init test_std(void)
0192 {
0193     struct pt_regs regs;
0194     unsigned long a = 0x1234;
0195     int stepped = -1;
0196 
0197     init_pt_regs(&regs);
0198     regs.gpr[3] = (unsigned long) &a;
0199     regs.gpr[5] = 0x5678;
0200 
0201     /* std r5, 0(r3) */
0202     stepped = emulate_step(&regs, ppc_inst(PPC_RAW_STD(5, 3, 0)));
0203     if (stepped == 1 && regs.gpr[5] == a)
0204         show_result("std", "PASS");
0205     else
0206         show_result("std", "FAIL");
0207 }
0208 
0209 static void __init test_pstd(void)
0210 {
0211     struct pt_regs regs;
0212     unsigned long a = 0x1234;
0213     int stepped = -1;
0214 
0215     if (!cpu_has_feature(CPU_FTR_ARCH_31)) {
0216         show_result("pstd", "SKIP (!CPU_FTR_ARCH_31)");
0217         return;
0218     }
0219 
0220     init_pt_regs(&regs);
0221     regs.gpr[3] = (unsigned long)&a;
0222     regs.gpr[5] = 0x5678;
0223 
0224     /* pstd r5, 0(r3), 0 */
0225     stepped = emulate_step(&regs, TEST_PSTD(5, 3, 0, 0));
0226     if (stepped == 1 || regs.gpr[5] == a)
0227         show_result("pstd", "PASS");
0228     else
0229         show_result("pstd", "FAIL");
0230 }
0231 
0232 static void __init test_ldarx_stdcx(void)
0233 {
0234     struct pt_regs regs;
0235     unsigned long a = 0x1234;
0236     int stepped = -1;
0237     unsigned long cr0_eq = 0x1 << 29; /* eq bit of CR0 */
0238 
0239     init_pt_regs(&regs);
0240     asm volatile("mfcr %0" : "=r"(regs.ccr));
0241 
0242 
0243     /*** ldarx ***/
0244 
0245     regs.gpr[3] = (unsigned long) &a;
0246     regs.gpr[4] = 0;
0247     regs.gpr[5] = 0x5678;
0248 
0249     /* ldarx r5, r3, r4, 0 */
0250     stepped = emulate_step(&regs, ppc_inst(PPC_RAW_LDARX(5, 3, 4, 0)));
0251 
0252     /*
0253      * Don't touch 'a' here. Touching 'a' can do Load/store
0254      * of 'a' which result in failure of subsequent stdcx.
0255      * Instead, use hardcoded value for comparison.
0256      */
0257     if (stepped <= 0 || regs.gpr[5] != 0x1234) {
0258         show_result("ldarx / stdcx.", "FAIL (ldarx)");
0259         return;
0260     }
0261 
0262 
0263     /*** stdcx. ***/
0264 
0265     regs.gpr[5] = 0x9ABC;
0266 
0267     /* stdcx. r5, r3, r4 */
0268     stepped = emulate_step(&regs, ppc_inst(PPC_RAW_STDCX(5, 3, 4)));
0269 
0270     /*
0271      * Two possible scenarios that indicates successful emulation
0272      * of stdcx. :
0273      *  1. Reservation is active and store is performed. In this
0274      *     case cr0.eq bit will be set to 1.
0275      *  2. Reservation is not active and store is not performed.
0276      *     In this case cr0.eq bit will be set to 0.
0277      */
0278     if (stepped == 1 && ((regs.gpr[5] == a && (regs.ccr & cr0_eq))
0279             || (regs.gpr[5] != a && !(regs.ccr & cr0_eq))))
0280         show_result("ldarx / stdcx.", "PASS");
0281     else
0282         show_result("ldarx / stdcx.", "FAIL (stdcx.)");
0283 }
0284 
0285 #ifdef CONFIG_PPC_FPU
0286 static void __init test_lfsx_stfsx(void)
0287 {
0288     struct pt_regs regs;
0289     union {
0290         float a;
0291         int b;
0292     } c;
0293     int cached_b;
0294     int stepped = -1;
0295 
0296     init_pt_regs(&regs);
0297 
0298 
0299     /*** lfsx ***/
0300 
0301     c.a = 123.45;
0302     cached_b = c.b;
0303 
0304     regs.gpr[3] = (unsigned long) &c.a;
0305     regs.gpr[4] = 0;
0306 
0307     /* lfsx frt10, r3, r4 */
0308     stepped = emulate_step(&regs, ppc_inst(PPC_RAW_LFSX(10, 3, 4)));
0309 
0310     if (stepped == 1)
0311         show_result("lfsx", "PASS");
0312     else
0313         show_result("lfsx", "FAIL");
0314 
0315 
0316     /*** stfsx ***/
0317 
0318     c.a = 678.91;
0319 
0320     /* stfsx frs10, r3, r4 */
0321     stepped = emulate_step(&regs, ppc_inst(PPC_RAW_STFSX(10, 3, 4)));
0322 
0323     if (stepped == 1 && c.b == cached_b)
0324         show_result("stfsx", "PASS");
0325     else
0326         show_result("stfsx", "FAIL");
0327 }
0328 
0329 static void __init test_plfs_pstfs(void)
0330 {
0331     struct pt_regs regs;
0332     union {
0333         float a;
0334         int b;
0335     } c;
0336     int cached_b;
0337     int stepped = -1;
0338 
0339     if (!cpu_has_feature(CPU_FTR_ARCH_31)) {
0340         show_result("pld", "SKIP (!CPU_FTR_ARCH_31)");
0341         return;
0342     }
0343 
0344     init_pt_regs(&regs);
0345 
0346 
0347     /*** plfs ***/
0348 
0349     c.a = 123.45;
0350     cached_b = c.b;
0351 
0352     regs.gpr[3] = (unsigned long)&c.a;
0353 
0354     /* plfs frt10, 0(r3), 0  */
0355     stepped = emulate_step(&regs, TEST_PLFS(10, 3, 0, 0));
0356 
0357     if (stepped == 1)
0358         show_result("plfs", "PASS");
0359     else
0360         show_result("plfs", "FAIL");
0361 
0362 
0363     /*** pstfs ***/
0364 
0365     c.a = 678.91;
0366 
0367     /* pstfs frs10, 0(r3), 0 */
0368     stepped = emulate_step(&regs, TEST_PSTFS(10, 3, 0, 0));
0369 
0370     if (stepped == 1 && c.b == cached_b)
0371         show_result("pstfs", "PASS");
0372     else
0373         show_result("pstfs", "FAIL");
0374 }
0375 
0376 static void __init test_lfdx_stfdx(void)
0377 {
0378     struct pt_regs regs;
0379     union {
0380         double a;
0381         long b;
0382     } c;
0383     long cached_b;
0384     int stepped = -1;
0385 
0386     init_pt_regs(&regs);
0387 
0388 
0389     /*** lfdx ***/
0390 
0391     c.a = 123456.78;
0392     cached_b = c.b;
0393 
0394     regs.gpr[3] = (unsigned long) &c.a;
0395     regs.gpr[4] = 0;
0396 
0397     /* lfdx frt10, r3, r4 */
0398     stepped = emulate_step(&regs, ppc_inst(PPC_RAW_LFDX(10, 3, 4)));
0399 
0400     if (stepped == 1)
0401         show_result("lfdx", "PASS");
0402     else
0403         show_result("lfdx", "FAIL");
0404 
0405 
0406     /*** stfdx ***/
0407 
0408     c.a = 987654.32;
0409 
0410     /* stfdx frs10, r3, r4 */
0411     stepped = emulate_step(&regs, ppc_inst(PPC_RAW_STFDX(10, 3, 4)));
0412 
0413     if (stepped == 1 && c.b == cached_b)
0414         show_result("stfdx", "PASS");
0415     else
0416         show_result("stfdx", "FAIL");
0417 }
0418 
0419 static void __init test_plfd_pstfd(void)
0420 {
0421     struct pt_regs regs;
0422     union {
0423         double a;
0424         long b;
0425     } c;
0426     long cached_b;
0427     int stepped = -1;
0428 
0429     if (!cpu_has_feature(CPU_FTR_ARCH_31)) {
0430         show_result("pld", "SKIP (!CPU_FTR_ARCH_31)");
0431         return;
0432     }
0433 
0434     init_pt_regs(&regs);
0435 
0436 
0437     /*** plfd ***/
0438 
0439     c.a = 123456.78;
0440     cached_b = c.b;
0441 
0442     regs.gpr[3] = (unsigned long)&c.a;
0443 
0444     /* plfd frt10, 0(r3), 0 */
0445     stepped = emulate_step(&regs, TEST_PLFD(10, 3, 0, 0));
0446 
0447     if (stepped == 1)
0448         show_result("plfd", "PASS");
0449     else
0450         show_result("plfd", "FAIL");
0451 
0452 
0453     /*** pstfd ***/
0454 
0455     c.a = 987654.32;
0456 
0457     /* pstfd frs10, 0(r3), 0 */
0458     stepped = emulate_step(&regs, TEST_PSTFD(10, 3, 0, 0));
0459 
0460     if (stepped == 1 && c.b == cached_b)
0461         show_result("pstfd", "PASS");
0462     else
0463         show_result("pstfd", "FAIL");
0464 }
0465 #else
0466 static void __init test_lfsx_stfsx(void)
0467 {
0468     show_result("lfsx", "SKIP (CONFIG_PPC_FPU is not set)");
0469     show_result("stfsx", "SKIP (CONFIG_PPC_FPU is not set)");
0470 }
0471 
0472 static void __init test_plfs_pstfs(void)
0473 {
0474     show_result("plfs", "SKIP (CONFIG_PPC_FPU is not set)");
0475     show_result("pstfs", "SKIP (CONFIG_PPC_FPU is not set)");
0476 }
0477 
0478 static void __init test_lfdx_stfdx(void)
0479 {
0480     show_result("lfdx", "SKIP (CONFIG_PPC_FPU is not set)");
0481     show_result("stfdx", "SKIP (CONFIG_PPC_FPU is not set)");
0482 }
0483 
0484 static void __init test_plfd_pstfd(void)
0485 {
0486     show_result("plfd", "SKIP (CONFIG_PPC_FPU is not set)");
0487     show_result("pstfd", "SKIP (CONFIG_PPC_FPU is not set)");
0488 }
0489 #endif /* CONFIG_PPC_FPU */
0490 
0491 #ifdef CONFIG_ALTIVEC
0492 static void __init test_lvx_stvx(void)
0493 {
0494     struct pt_regs regs;
0495     union {
0496         vector128 a;
0497         u32 b[4];
0498     } c;
0499     u32 cached_b[4];
0500     int stepped = -1;
0501 
0502     init_pt_regs(&regs);
0503 
0504 
0505     /*** lvx ***/
0506 
0507     cached_b[0] = c.b[0] = 923745;
0508     cached_b[1] = c.b[1] = 2139478;
0509     cached_b[2] = c.b[2] = 9012;
0510     cached_b[3] = c.b[3] = 982134;
0511 
0512     regs.gpr[3] = (unsigned long) &c.a;
0513     regs.gpr[4] = 0;
0514 
0515     /* lvx vrt10, r3, r4 */
0516     stepped = emulate_step(&regs, ppc_inst(PPC_RAW_LVX(10, 3, 4)));
0517 
0518     if (stepped == 1)
0519         show_result("lvx", "PASS");
0520     else
0521         show_result("lvx", "FAIL");
0522 
0523 
0524     /*** stvx ***/
0525 
0526     c.b[0] = 4987513;
0527     c.b[1] = 84313948;
0528     c.b[2] = 71;
0529     c.b[3] = 498532;
0530 
0531     /* stvx vrs10, r3, r4 */
0532     stepped = emulate_step(&regs, ppc_inst(PPC_RAW_STVX(10, 3, 4)));
0533 
0534     if (stepped == 1 && cached_b[0] == c.b[0] && cached_b[1] == c.b[1] &&
0535         cached_b[2] == c.b[2] && cached_b[3] == c.b[3])
0536         show_result("stvx", "PASS");
0537     else
0538         show_result("stvx", "FAIL");
0539 }
0540 #else
0541 static void __init test_lvx_stvx(void)
0542 {
0543     show_result("lvx", "SKIP (CONFIG_ALTIVEC is not set)");
0544     show_result("stvx", "SKIP (CONFIG_ALTIVEC is not set)");
0545 }
0546 #endif /* CONFIG_ALTIVEC */
0547 
0548 #ifdef CONFIG_VSX
0549 static void __init test_lxvd2x_stxvd2x(void)
0550 {
0551     struct pt_regs regs;
0552     union {
0553         vector128 a;
0554         u32 b[4];
0555     } c;
0556     u32 cached_b[4];
0557     int stepped = -1;
0558 
0559     init_pt_regs(&regs);
0560 
0561 
0562     /*** lxvd2x ***/
0563 
0564     cached_b[0] = c.b[0] = 18233;
0565     cached_b[1] = c.b[1] = 34863571;
0566     cached_b[2] = c.b[2] = 834;
0567     cached_b[3] = c.b[3] = 6138911;
0568 
0569     regs.gpr[3] = (unsigned long) &c.a;
0570     regs.gpr[4] = 0;
0571 
0572     /* lxvd2x vsr39, r3, r4 */
0573     stepped = emulate_step(&regs, ppc_inst(PPC_RAW_LXVD2X(39, R3, R4)));
0574 
0575     if (stepped == 1 && cpu_has_feature(CPU_FTR_VSX)) {
0576         show_result("lxvd2x", "PASS");
0577     } else {
0578         if (!cpu_has_feature(CPU_FTR_VSX))
0579             show_result("lxvd2x", "PASS (!CPU_FTR_VSX)");
0580         else
0581             show_result("lxvd2x", "FAIL");
0582     }
0583 
0584 
0585     /*** stxvd2x ***/
0586 
0587     c.b[0] = 21379463;
0588     c.b[1] = 87;
0589     c.b[2] = 374234;
0590     c.b[3] = 4;
0591 
0592     /* stxvd2x vsr39, r3, r4 */
0593     stepped = emulate_step(&regs, ppc_inst(PPC_RAW_STXVD2X(39, R3, R4)));
0594 
0595     if (stepped == 1 && cached_b[0] == c.b[0] && cached_b[1] == c.b[1] &&
0596         cached_b[2] == c.b[2] && cached_b[3] == c.b[3] &&
0597         cpu_has_feature(CPU_FTR_VSX)) {
0598         show_result("stxvd2x", "PASS");
0599     } else {
0600         if (!cpu_has_feature(CPU_FTR_VSX))
0601             show_result("stxvd2x", "PASS (!CPU_FTR_VSX)");
0602         else
0603             show_result("stxvd2x", "FAIL");
0604     }
0605 }
0606 #else
0607 static void __init test_lxvd2x_stxvd2x(void)
0608 {
0609     show_result("lxvd2x", "SKIP (CONFIG_VSX is not set)");
0610     show_result("stxvd2x", "SKIP (CONFIG_VSX is not set)");
0611 }
0612 #endif /* CONFIG_VSX */
0613 
0614 #ifdef CONFIG_VSX
0615 static void __init test_lxvp_stxvp(void)
0616 {
0617     struct pt_regs regs;
0618     union {
0619         vector128 a;
0620         u32 b[4];
0621     } c[2];
0622     u32 cached_b[8];
0623     int stepped = -1;
0624 
0625     if (!cpu_has_feature(CPU_FTR_ARCH_31)) {
0626         show_result("lxvp", "SKIP (!CPU_FTR_ARCH_31)");
0627         show_result("stxvp", "SKIP (!CPU_FTR_ARCH_31)");
0628         return;
0629     }
0630 
0631     init_pt_regs(&regs);
0632 
0633     /*** lxvp ***/
0634 
0635     cached_b[0] = c[0].b[0] = 18233;
0636     cached_b[1] = c[0].b[1] = 34863571;
0637     cached_b[2] = c[0].b[2] = 834;
0638     cached_b[3] = c[0].b[3] = 6138911;
0639     cached_b[4] = c[1].b[0] = 1234;
0640     cached_b[5] = c[1].b[1] = 5678;
0641     cached_b[6] = c[1].b[2] = 91011;
0642     cached_b[7] = c[1].b[3] = 121314;
0643 
0644     regs.gpr[4] = (unsigned long)&c[0].a;
0645 
0646     /*
0647      * lxvp XTp,DQ(RA)
0648      * XTp = 32xTX + 2xTp
0649      * let TX=1 Tp=1 RA=4 DQ=0
0650      */
0651     stepped = emulate_step(&regs, ppc_inst(PPC_RAW_LXVP(34, 4, 0)));
0652 
0653     if (stepped == 1 && cpu_has_feature(CPU_FTR_VSX)) {
0654         show_result("lxvp", "PASS");
0655     } else {
0656         if (!cpu_has_feature(CPU_FTR_VSX))
0657             show_result("lxvp", "PASS (!CPU_FTR_VSX)");
0658         else
0659             show_result("lxvp", "FAIL");
0660     }
0661 
0662     /*** stxvp ***/
0663 
0664     c[0].b[0] = 21379463;
0665     c[0].b[1] = 87;
0666     c[0].b[2] = 374234;
0667     c[0].b[3] = 4;
0668     c[1].b[0] = 90;
0669     c[1].b[1] = 122;
0670     c[1].b[2] = 555;
0671     c[1].b[3] = 32144;
0672 
0673     /*
0674      * stxvp XSp,DQ(RA)
0675      * XSp = 32xSX + 2xSp
0676      * let SX=1 Sp=1 RA=4 DQ=0
0677      */
0678     stepped = emulate_step(&regs, ppc_inst(PPC_RAW_STXVP(34, 4, 0)));
0679 
0680     if (stepped == 1 && cached_b[0] == c[0].b[0] && cached_b[1] == c[0].b[1] &&
0681         cached_b[2] == c[0].b[2] && cached_b[3] == c[0].b[3] &&
0682         cached_b[4] == c[1].b[0] && cached_b[5] == c[1].b[1] &&
0683         cached_b[6] == c[1].b[2] && cached_b[7] == c[1].b[3] &&
0684         cpu_has_feature(CPU_FTR_VSX)) {
0685         show_result("stxvp", "PASS");
0686     } else {
0687         if (!cpu_has_feature(CPU_FTR_VSX))
0688             show_result("stxvp", "PASS (!CPU_FTR_VSX)");
0689         else
0690             show_result("stxvp", "FAIL");
0691     }
0692 }
0693 #else
0694 static void __init test_lxvp_stxvp(void)
0695 {
0696     show_result("lxvp", "SKIP (CONFIG_VSX is not set)");
0697     show_result("stxvp", "SKIP (CONFIG_VSX is not set)");
0698 }
0699 #endif /* CONFIG_VSX */
0700 
0701 #ifdef CONFIG_VSX
0702 static void __init test_lxvpx_stxvpx(void)
0703 {
0704     struct pt_regs regs;
0705     union {
0706         vector128 a;
0707         u32 b[4];
0708     } c[2];
0709     u32 cached_b[8];
0710     int stepped = -1;
0711 
0712     if (!cpu_has_feature(CPU_FTR_ARCH_31)) {
0713         show_result("lxvpx", "SKIP (!CPU_FTR_ARCH_31)");
0714         show_result("stxvpx", "SKIP (!CPU_FTR_ARCH_31)");
0715         return;
0716     }
0717 
0718     init_pt_regs(&regs);
0719 
0720     /*** lxvpx ***/
0721 
0722     cached_b[0] = c[0].b[0] = 18233;
0723     cached_b[1] = c[0].b[1] = 34863571;
0724     cached_b[2] = c[0].b[2] = 834;
0725     cached_b[3] = c[0].b[3] = 6138911;
0726     cached_b[4] = c[1].b[0] = 1234;
0727     cached_b[5] = c[1].b[1] = 5678;
0728     cached_b[6] = c[1].b[2] = 91011;
0729     cached_b[7] = c[1].b[3] = 121314;
0730 
0731     regs.gpr[3] = (unsigned long)&c[0].a;
0732     regs.gpr[4] = 0;
0733 
0734     /*
0735      * lxvpx XTp,RA,RB
0736      * XTp = 32xTX + 2xTp
0737      * let TX=1 Tp=1 RA=3 RB=4
0738      */
0739     stepped = emulate_step(&regs, ppc_inst(PPC_RAW_LXVPX(34, 3, 4)));
0740 
0741     if (stepped == 1 && cpu_has_feature(CPU_FTR_VSX)) {
0742         show_result("lxvpx", "PASS");
0743     } else {
0744         if (!cpu_has_feature(CPU_FTR_VSX))
0745             show_result("lxvpx", "PASS (!CPU_FTR_VSX)");
0746         else
0747             show_result("lxvpx", "FAIL");
0748     }
0749 
0750     /*** stxvpx ***/
0751 
0752     c[0].b[0] = 21379463;
0753     c[0].b[1] = 87;
0754     c[0].b[2] = 374234;
0755     c[0].b[3] = 4;
0756     c[1].b[0] = 90;
0757     c[1].b[1] = 122;
0758     c[1].b[2] = 555;
0759     c[1].b[3] = 32144;
0760 
0761     /*
0762      * stxvpx XSp,RA,RB
0763      * XSp = 32xSX + 2xSp
0764      * let SX=1 Sp=1 RA=3 RB=4
0765      */
0766     stepped = emulate_step(&regs, ppc_inst(PPC_RAW_STXVPX(34, 3, 4)));
0767 
0768     if (stepped == 1 && cached_b[0] == c[0].b[0] && cached_b[1] == c[0].b[1] &&
0769         cached_b[2] == c[0].b[2] && cached_b[3] == c[0].b[3] &&
0770         cached_b[4] == c[1].b[0] && cached_b[5] == c[1].b[1] &&
0771         cached_b[6] == c[1].b[2] && cached_b[7] == c[1].b[3] &&
0772         cpu_has_feature(CPU_FTR_VSX)) {
0773         show_result("stxvpx", "PASS");
0774     } else {
0775         if (!cpu_has_feature(CPU_FTR_VSX))
0776             show_result("stxvpx", "PASS (!CPU_FTR_VSX)");
0777         else
0778             show_result("stxvpx", "FAIL");
0779     }
0780 }
0781 #else
0782 static void __init test_lxvpx_stxvpx(void)
0783 {
0784     show_result("lxvpx", "SKIP (CONFIG_VSX is not set)");
0785     show_result("stxvpx", "SKIP (CONFIG_VSX is not set)");
0786 }
0787 #endif /* CONFIG_VSX */
0788 
0789 #ifdef CONFIG_VSX
0790 static void __init test_plxvp_pstxvp(void)
0791 {
0792     ppc_inst_t instr;
0793     struct pt_regs regs;
0794     union {
0795         vector128 a;
0796         u32 b[4];
0797     } c[2];
0798     u32 cached_b[8];
0799     int stepped = -1;
0800 
0801     if (!cpu_has_feature(CPU_FTR_ARCH_31)) {
0802         show_result("plxvp", "SKIP (!CPU_FTR_ARCH_31)");
0803         show_result("pstxvp", "SKIP (!CPU_FTR_ARCH_31)");
0804         return;
0805     }
0806 
0807     /*** plxvp ***/
0808 
0809     cached_b[0] = c[0].b[0] = 18233;
0810     cached_b[1] = c[0].b[1] = 34863571;
0811     cached_b[2] = c[0].b[2] = 834;
0812     cached_b[3] = c[0].b[3] = 6138911;
0813     cached_b[4] = c[1].b[0] = 1234;
0814     cached_b[5] = c[1].b[1] = 5678;
0815     cached_b[6] = c[1].b[2] = 91011;
0816     cached_b[7] = c[1].b[3] = 121314;
0817 
0818     init_pt_regs(&regs);
0819     regs.gpr[3] = (unsigned long)&c[0].a;
0820 
0821     /*
0822      * plxvp XTp,D(RA),R
0823      * XTp = 32xTX + 2xTp
0824      * let RA=3 R=0 D=d0||d1=0 R=0 Tp=1 TX=1
0825      */
0826     instr = ppc_inst_prefix(PPC_RAW_PLXVP_P(34, 0, 3, 0), PPC_RAW_PLXVP_S(34, 0, 3, 0));
0827 
0828     stepped = emulate_step(&regs, instr);
0829     if (stepped == 1 && cpu_has_feature(CPU_FTR_VSX)) {
0830         show_result("plxvp", "PASS");
0831     } else {
0832         if (!cpu_has_feature(CPU_FTR_VSX))
0833             show_result("plxvp", "PASS (!CPU_FTR_VSX)");
0834         else
0835             show_result("plxvp", "FAIL");
0836     }
0837 
0838     /*** pstxvp ***/
0839 
0840     c[0].b[0] = 21379463;
0841     c[0].b[1] = 87;
0842     c[0].b[2] = 374234;
0843     c[0].b[3] = 4;
0844     c[1].b[0] = 90;
0845     c[1].b[1] = 122;
0846     c[1].b[2] = 555;
0847     c[1].b[3] = 32144;
0848 
0849     /*
0850      * pstxvp XSp,D(RA),R
0851      * XSp = 32xSX + 2xSp
0852      * let RA=3 D=d0||d1=0 R=0 Sp=1 SX=1
0853      */
0854     instr = ppc_inst_prefix(PPC_RAW_PSTXVP_P(34, 0, 3, 0), PPC_RAW_PSTXVP_S(34, 0, 3, 0));
0855 
0856     stepped = emulate_step(&regs, instr);
0857 
0858     if (stepped == 1 && cached_b[0] == c[0].b[0] && cached_b[1] == c[0].b[1] &&
0859         cached_b[2] == c[0].b[2] && cached_b[3] == c[0].b[3] &&
0860         cached_b[4] == c[1].b[0] && cached_b[5] == c[1].b[1] &&
0861         cached_b[6] == c[1].b[2] && cached_b[7] == c[1].b[3] &&
0862         cpu_has_feature(CPU_FTR_VSX)) {
0863         show_result("pstxvp", "PASS");
0864     } else {
0865         if (!cpu_has_feature(CPU_FTR_VSX))
0866             show_result("pstxvp", "PASS (!CPU_FTR_VSX)");
0867         else
0868             show_result("pstxvp", "FAIL");
0869     }
0870 }
0871 #else
0872 static void __init test_plxvp_pstxvp(void)
0873 {
0874     show_result("plxvp", "SKIP (CONFIG_VSX is not set)");
0875     show_result("pstxvp", "SKIP (CONFIG_VSX is not set)");
0876 }
0877 #endif /* CONFIG_VSX */
0878 
0879 static void __init run_tests_load_store(void)
0880 {
0881     test_ld();
0882     test_pld();
0883     test_lwz();
0884     test_plwz();
0885     test_lwzx();
0886     test_std();
0887     test_pstd();
0888     test_ldarx_stdcx();
0889     test_lfsx_stfsx();
0890     test_plfs_pstfs();
0891     test_lfdx_stfdx();
0892     test_plfd_pstfd();
0893     test_lvx_stvx();
0894     test_lxvd2x_stxvd2x();
0895     test_lxvp_stxvp();
0896     test_lxvpx_stxvpx();
0897     test_plxvp_pstxvp();
0898 }
0899 
0900 struct compute_test {
0901     char *mnemonic;
0902     unsigned long cpu_feature;
0903     struct {
0904         char *descr;
0905         unsigned long flags;
0906         ppc_inst_t instr;
0907         struct pt_regs regs;
0908     } subtests[MAX_SUBTESTS + 1];
0909 };
0910 
0911 /* Extreme values for si0||si1 (the MLS:D-form 34 bit immediate field) */
0912 #define SI_MIN BIT(33)
0913 #define SI_MAX (BIT(33) - 1)
0914 #define SI_UMAX (BIT(34) - 1)
0915 
0916 static struct compute_test compute_tests[] = {
0917     {
0918         .mnemonic = "nop",
0919         .subtests = {
0920             {
0921                 .descr = "R0 = LONG_MAX",
0922                 .instr = ppc_inst(PPC_RAW_NOP()),
0923                 .regs = {
0924                     .gpr[0] = LONG_MAX,
0925                 }
0926             }
0927         }
0928     },
0929     {
0930         .mnemonic = "setb",
0931         .cpu_feature = CPU_FTR_ARCH_300,
0932         .subtests = {
0933             {
0934                 .descr = "BFA = 1, CR = GT",
0935                 .instr = ppc_inst(PPC_RAW_SETB(20, 1)),
0936                 .regs = {
0937                     .ccr = 0x4000000,
0938                 }
0939             },
0940             {
0941                 .descr = "BFA = 4, CR = LT",
0942                 .instr = ppc_inst(PPC_RAW_SETB(20, 4)),
0943                 .regs = {
0944                     .ccr = 0x8000,
0945                 }
0946             },
0947             {
0948                 .descr = "BFA = 5, CR = EQ",
0949                 .instr = ppc_inst(PPC_RAW_SETB(20, 5)),
0950                 .regs = {
0951                     .ccr = 0x200,
0952                 }
0953             }
0954         }
0955     },
0956     {
0957         .mnemonic = "add",
0958         .subtests = {
0959             {
0960                 .descr = "RA = LONG_MIN, RB = LONG_MIN",
0961                 .instr = ppc_inst(PPC_RAW_ADD(20, 21, 22)),
0962                 .regs = {
0963                     .gpr[21] = LONG_MIN,
0964                     .gpr[22] = LONG_MIN,
0965                 }
0966             },
0967             {
0968                 .descr = "RA = LONG_MIN, RB = LONG_MAX",
0969                 .instr = ppc_inst(PPC_RAW_ADD(20, 21, 22)),
0970                 .regs = {
0971                     .gpr[21] = LONG_MIN,
0972                     .gpr[22] = LONG_MAX,
0973                 }
0974             },
0975             {
0976                 .descr = "RA = LONG_MAX, RB = LONG_MAX",
0977                 .instr = ppc_inst(PPC_RAW_ADD(20, 21, 22)),
0978                 .regs = {
0979                     .gpr[21] = LONG_MAX,
0980                     .gpr[22] = LONG_MAX,
0981                 }
0982             },
0983             {
0984                 .descr = "RA = ULONG_MAX, RB = ULONG_MAX",
0985                 .instr = ppc_inst(PPC_RAW_ADD(20, 21, 22)),
0986                 .regs = {
0987                     .gpr[21] = ULONG_MAX,
0988                     .gpr[22] = ULONG_MAX,
0989                 }
0990             },
0991             {
0992                 .descr = "RA = ULONG_MAX, RB = 0x1",
0993                 .instr = ppc_inst(PPC_RAW_ADD(20, 21, 22)),
0994                 .regs = {
0995                     .gpr[21] = ULONG_MAX,
0996                     .gpr[22] = 0x1,
0997                 }
0998             },
0999             {
1000                 .descr = "RA = INT_MIN, RB = INT_MIN",
1001                 .instr = ppc_inst(PPC_RAW_ADD(20, 21, 22)),
1002                 .regs = {
1003                     .gpr[21] = INT_MIN,
1004                     .gpr[22] = INT_MIN,
1005                 }
1006             },
1007             {
1008                 .descr = "RA = INT_MIN, RB = INT_MAX",
1009                 .instr = ppc_inst(PPC_RAW_ADD(20, 21, 22)),
1010                 .regs = {
1011                     .gpr[21] = INT_MIN,
1012                     .gpr[22] = INT_MAX,
1013                 }
1014             },
1015             {
1016                 .descr = "RA = INT_MAX, RB = INT_MAX",
1017                 .instr = ppc_inst(PPC_RAW_ADD(20, 21, 22)),
1018                 .regs = {
1019                     .gpr[21] = INT_MAX,
1020                     .gpr[22] = INT_MAX,
1021                 }
1022             },
1023             {
1024                 .descr = "RA = UINT_MAX, RB = UINT_MAX",
1025                 .instr = ppc_inst(PPC_RAW_ADD(20, 21, 22)),
1026                 .regs = {
1027                     .gpr[21] = UINT_MAX,
1028                     .gpr[22] = UINT_MAX,
1029                 }
1030             },
1031             {
1032                 .descr = "RA = UINT_MAX, RB = 0x1",
1033                 .instr = ppc_inst(PPC_RAW_ADD(20, 21, 22)),
1034                 .regs = {
1035                     .gpr[21] = UINT_MAX,
1036                     .gpr[22] = 0x1,
1037                 }
1038             }
1039         }
1040     },
1041     {
1042         .mnemonic = "add.",
1043         .subtests = {
1044             {
1045                 .descr = "RA = LONG_MIN, RB = LONG_MIN",
1046                 .flags = IGNORE_CCR,
1047                 .instr = ppc_inst(PPC_RAW_ADD_DOT(20, 21, 22)),
1048                 .regs = {
1049                     .gpr[21] = LONG_MIN,
1050                     .gpr[22] = LONG_MIN,
1051                 }
1052             },
1053             {
1054                 .descr = "RA = LONG_MIN, RB = LONG_MAX",
1055                 .instr = ppc_inst(PPC_RAW_ADD_DOT(20, 21, 22)),
1056                 .regs = {
1057                     .gpr[21] = LONG_MIN,
1058                     .gpr[22] = LONG_MAX,
1059                 }
1060             },
1061             {
1062                 .descr = "RA = LONG_MAX, RB = LONG_MAX",
1063                 .flags = IGNORE_CCR,
1064                 .instr = ppc_inst(PPC_RAW_ADD_DOT(20, 21, 22)),
1065                 .regs = {
1066                     .gpr[21] = LONG_MAX,
1067                     .gpr[22] = LONG_MAX,
1068                 }
1069             },
1070             {
1071                 .descr = "RA = ULONG_MAX, RB = ULONG_MAX",
1072                 .instr = ppc_inst(PPC_RAW_ADD_DOT(20, 21, 22)),
1073                 .regs = {
1074                     .gpr[21] = ULONG_MAX,
1075                     .gpr[22] = ULONG_MAX,
1076                 }
1077             },
1078             {
1079                 .descr = "RA = ULONG_MAX, RB = 0x1",
1080                 .instr = ppc_inst(PPC_RAW_ADD_DOT(20, 21, 22)),
1081                 .regs = {
1082                     .gpr[21] = ULONG_MAX,
1083                     .gpr[22] = 0x1,
1084                 }
1085             },
1086             {
1087                 .descr = "RA = INT_MIN, RB = INT_MIN",
1088                 .instr = ppc_inst(PPC_RAW_ADD_DOT(20, 21, 22)),
1089                 .regs = {
1090                     .gpr[21] = INT_MIN,
1091                     .gpr[22] = INT_MIN,
1092                 }
1093             },
1094             {
1095                 .descr = "RA = INT_MIN, RB = INT_MAX",
1096                 .instr = ppc_inst(PPC_RAW_ADD_DOT(20, 21, 22)),
1097                 .regs = {
1098                     .gpr[21] = INT_MIN,
1099                     .gpr[22] = INT_MAX,
1100                 }
1101             },
1102             {
1103                 .descr = "RA = INT_MAX, RB = INT_MAX",
1104                 .instr = ppc_inst(PPC_RAW_ADD_DOT(20, 21, 22)),
1105                 .regs = {
1106                     .gpr[21] = INT_MAX,
1107                     .gpr[22] = INT_MAX,
1108                 }
1109             },
1110             {
1111                 .descr = "RA = UINT_MAX, RB = UINT_MAX",
1112                 .instr = ppc_inst(PPC_RAW_ADD_DOT(20, 21, 22)),
1113                 .regs = {
1114                     .gpr[21] = UINT_MAX,
1115                     .gpr[22] = UINT_MAX,
1116                 }
1117             },
1118             {
1119                 .descr = "RA = UINT_MAX, RB = 0x1",
1120                 .instr = ppc_inst(PPC_RAW_ADD_DOT(20, 21, 22)),
1121                 .regs = {
1122                     .gpr[21] = UINT_MAX,
1123                     .gpr[22] = 0x1,
1124                 }
1125             }
1126         }
1127     },
1128     {
1129         .mnemonic = "addc",
1130         .subtests = {
1131             {
1132                 .descr = "RA = LONG_MIN, RB = LONG_MIN",
1133                 .instr = ppc_inst(PPC_RAW_ADDC(20, 21, 22)),
1134                 .regs = {
1135                     .gpr[21] = LONG_MIN,
1136                     .gpr[22] = LONG_MIN,
1137                 }
1138             },
1139             {
1140                 .descr = "RA = LONG_MIN, RB = LONG_MAX",
1141                 .instr = ppc_inst(PPC_RAW_ADDC(20, 21, 22)),
1142                 .regs = {
1143                     .gpr[21] = LONG_MIN,
1144                     .gpr[22] = LONG_MAX,
1145                 }
1146             },
1147             {
1148                 .descr = "RA = LONG_MAX, RB = LONG_MAX",
1149                 .instr = ppc_inst(PPC_RAW_ADDC(20, 21, 22)),
1150                 .regs = {
1151                     .gpr[21] = LONG_MAX,
1152                     .gpr[22] = LONG_MAX,
1153                 }
1154             },
1155             {
1156                 .descr = "RA = ULONG_MAX, RB = ULONG_MAX",
1157                 .instr = ppc_inst(PPC_RAW_ADDC(20, 21, 22)),
1158                 .regs = {
1159                     .gpr[21] = ULONG_MAX,
1160                     .gpr[22] = ULONG_MAX,
1161                 }
1162             },
1163             {
1164                 .descr = "RA = ULONG_MAX, RB = 0x1",
1165                 .instr = ppc_inst(PPC_RAW_ADDC(20, 21, 22)),
1166                 .regs = {
1167                     .gpr[21] = ULONG_MAX,
1168                     .gpr[22] = 0x1,
1169                 }
1170             },
1171             {
1172                 .descr = "RA = INT_MIN, RB = INT_MIN",
1173                 .instr = ppc_inst(PPC_RAW_ADDC(20, 21, 22)),
1174                 .regs = {
1175                     .gpr[21] = INT_MIN,
1176                     .gpr[22] = INT_MIN,
1177                 }
1178             },
1179             {
1180                 .descr = "RA = INT_MIN, RB = INT_MAX",
1181                 .instr = ppc_inst(PPC_RAW_ADDC(20, 21, 22)),
1182                 .regs = {
1183                     .gpr[21] = INT_MIN,
1184                     .gpr[22] = INT_MAX,
1185                 }
1186             },
1187             {
1188                 .descr = "RA = INT_MAX, RB = INT_MAX",
1189                 .instr = ppc_inst(PPC_RAW_ADDC(20, 21, 22)),
1190                 .regs = {
1191                     .gpr[21] = INT_MAX,
1192                     .gpr[22] = INT_MAX,
1193                 }
1194             },
1195             {
1196                 .descr = "RA = UINT_MAX, RB = UINT_MAX",
1197                 .instr = ppc_inst(PPC_RAW_ADDC(20, 21, 22)),
1198                 .regs = {
1199                     .gpr[21] = UINT_MAX,
1200                     .gpr[22] = UINT_MAX,
1201                 }
1202             },
1203             {
1204                 .descr = "RA = UINT_MAX, RB = 0x1",
1205                 .instr = ppc_inst(PPC_RAW_ADDC(20, 21, 22)),
1206                 .regs = {
1207                     .gpr[21] = UINT_MAX,
1208                     .gpr[22] = 0x1,
1209                 }
1210             },
1211             {
1212                 .descr = "RA = LONG_MIN | INT_MIN, RB = LONG_MIN | INT_MIN",
1213                 .instr = ppc_inst(PPC_RAW_ADDC(20, 21, 22)),
1214                 .regs = {
1215                     .gpr[21] = LONG_MIN | (uint)INT_MIN,
1216                     .gpr[22] = LONG_MIN | (uint)INT_MIN,
1217                 }
1218             }
1219         }
1220     },
1221     {
1222         .mnemonic = "addc.",
1223         .subtests = {
1224             {
1225                 .descr = "RA = LONG_MIN, RB = LONG_MIN",
1226                 .flags = IGNORE_CCR,
1227                 .instr = ppc_inst(PPC_RAW_ADDC_DOT(20, 21, 22)),
1228                 .regs = {
1229                     .gpr[21] = LONG_MIN,
1230                     .gpr[22] = LONG_MIN,
1231                 }
1232             },
1233             {
1234                 .descr = "RA = LONG_MIN, RB = LONG_MAX",
1235                 .instr = ppc_inst(PPC_RAW_ADDC_DOT(20, 21, 22)),
1236                 .regs = {
1237                     .gpr[21] = LONG_MIN,
1238                     .gpr[22] = LONG_MAX,
1239                 }
1240             },
1241             {
1242                 .descr = "RA = LONG_MAX, RB = LONG_MAX",
1243                 .flags = IGNORE_CCR,
1244                 .instr = ppc_inst(PPC_RAW_ADDC_DOT(20, 21, 22)),
1245                 .regs = {
1246                     .gpr[21] = LONG_MAX,
1247                     .gpr[22] = LONG_MAX,
1248                 }
1249             },
1250             {
1251                 .descr = "RA = ULONG_MAX, RB = ULONG_MAX",
1252                 .instr = ppc_inst(PPC_RAW_ADDC_DOT(20, 21, 22)),
1253                 .regs = {
1254                     .gpr[21] = ULONG_MAX,
1255                     .gpr[22] = ULONG_MAX,
1256                 }
1257             },
1258             {
1259                 .descr = "RA = ULONG_MAX, RB = 0x1",
1260                 .instr = ppc_inst(PPC_RAW_ADDC_DOT(20, 21, 22)),
1261                 .regs = {
1262                     .gpr[21] = ULONG_MAX,
1263                     .gpr[22] = 0x1,
1264                 }
1265             },
1266             {
1267                 .descr = "RA = INT_MIN, RB = INT_MIN",
1268                 .instr = ppc_inst(PPC_RAW_ADDC_DOT(20, 21, 22)),
1269                 .regs = {
1270                     .gpr[21] = INT_MIN,
1271                     .gpr[22] = INT_MIN,
1272                 }
1273             },
1274             {
1275                 .descr = "RA = INT_MIN, RB = INT_MAX",
1276                 .instr = ppc_inst(PPC_RAW_ADDC_DOT(20, 21, 22)),
1277                 .regs = {
1278                     .gpr[21] = INT_MIN,
1279                     .gpr[22] = INT_MAX,
1280                 }
1281             },
1282             {
1283                 .descr = "RA = INT_MAX, RB = INT_MAX",
1284                 .instr = ppc_inst(PPC_RAW_ADDC_DOT(20, 21, 22)),
1285                 .regs = {
1286                     .gpr[21] = INT_MAX,
1287                     .gpr[22] = INT_MAX,
1288                 }
1289             },
1290             {
1291                 .descr = "RA = UINT_MAX, RB = UINT_MAX",
1292                 .instr = ppc_inst(PPC_RAW_ADDC_DOT(20, 21, 22)),
1293                 .regs = {
1294                     .gpr[21] = UINT_MAX,
1295                     .gpr[22] = UINT_MAX,
1296                 }
1297             },
1298             {
1299                 .descr = "RA = UINT_MAX, RB = 0x1",
1300                 .instr = ppc_inst(PPC_RAW_ADDC_DOT(20, 21, 22)),
1301                 .regs = {
1302                     .gpr[21] = UINT_MAX,
1303                     .gpr[22] = 0x1,
1304                 }
1305             },
1306             {
1307                 .descr = "RA = LONG_MIN | INT_MIN, RB = LONG_MIN | INT_MIN",
1308                 .instr = ppc_inst(PPC_RAW_ADDC_DOT(20, 21, 22)),
1309                 .regs = {
1310                     .gpr[21] = LONG_MIN | (uint)INT_MIN,
1311                     .gpr[22] = LONG_MIN | (uint)INT_MIN,
1312                 }
1313             }
1314         }
1315     },
1316     {
1317         .mnemonic = "divde",
1318         .subtests = {
1319             {
1320                 .descr = "RA = LONG_MIN, RB = LONG_MIN",
1321                 .instr = ppc_inst(PPC_RAW_DIVDE(20, 21, 22)),
1322                 .regs = {
1323                     .gpr[21] = LONG_MIN,
1324                     .gpr[22] = LONG_MIN,
1325                 }
1326             },
1327             {
1328                 .descr = "RA = 1L, RB = 0",
1329                 .instr = ppc_inst(PPC_RAW_DIVDE(20, 21, 22)),
1330                 .flags = IGNORE_GPR(20),
1331                 .regs = {
1332                     .gpr[21] = 1L,
1333                     .gpr[22] = 0,
1334                 }
1335             },
1336             {
1337                 .descr = "RA = LONG_MIN, RB = LONG_MAX",
1338                 .instr = ppc_inst(PPC_RAW_DIVDE(20, 21, 22)),
1339                 .regs = {
1340                     .gpr[21] = LONG_MIN,
1341                     .gpr[22] = LONG_MAX,
1342                 }
1343             }
1344         }
1345     },
1346     {
1347         .mnemonic = "divde.",
1348         .subtests = {
1349             {
1350                 .descr = "RA = LONG_MIN, RB = LONG_MIN",
1351                 .instr = ppc_inst(PPC_RAW_DIVDE_DOT(20, 21, 22)),
1352                 .regs = {
1353                     .gpr[21] = LONG_MIN,
1354                     .gpr[22] = LONG_MIN,
1355                 }
1356             },
1357             {
1358                 .descr = "RA = 1L, RB = 0",
1359                 .instr = ppc_inst(PPC_RAW_DIVDE_DOT(20, 21, 22)),
1360                 .flags = IGNORE_GPR(20),
1361                 .regs = {
1362                     .gpr[21] = 1L,
1363                     .gpr[22] = 0,
1364                 }
1365             },
1366             {
1367                 .descr = "RA = LONG_MIN, RB = LONG_MAX",
1368                 .instr = ppc_inst(PPC_RAW_DIVDE_DOT(20, 21, 22)),
1369                 .regs = {
1370                     .gpr[21] = LONG_MIN,
1371                     .gpr[22] = LONG_MAX,
1372                 }
1373             }
1374         }
1375     },
1376     {
1377         .mnemonic = "divdeu",
1378         .subtests = {
1379             {
1380                 .descr = "RA = LONG_MIN, RB = LONG_MIN",
1381                 .instr = ppc_inst(PPC_RAW_DIVDEU(20, 21, 22)),
1382                 .flags = IGNORE_GPR(20),
1383                 .regs = {
1384                     .gpr[21] = LONG_MIN,
1385                     .gpr[22] = LONG_MIN,
1386                 }
1387             },
1388             {
1389                 .descr = "RA = 1L, RB = 0",
1390                 .instr = ppc_inst(PPC_RAW_DIVDEU(20, 21, 22)),
1391                 .flags = IGNORE_GPR(20),
1392                 .regs = {
1393                     .gpr[21] = 1L,
1394                     .gpr[22] = 0,
1395                 }
1396             },
1397             {
1398                 .descr = "RA = LONG_MIN, RB = LONG_MAX",
1399                 .instr = ppc_inst(PPC_RAW_DIVDEU(20, 21, 22)),
1400                 .regs = {
1401                     .gpr[21] = LONG_MIN,
1402                     .gpr[22] = LONG_MAX,
1403                 }
1404             },
1405             {
1406                 .descr = "RA = LONG_MAX - 1, RB = LONG_MAX",
1407                 .instr = ppc_inst(PPC_RAW_DIVDEU(20, 21, 22)),
1408                 .regs = {
1409                     .gpr[21] = LONG_MAX - 1,
1410                     .gpr[22] = LONG_MAX,
1411                 }
1412             },
1413             {
1414                 .descr = "RA = LONG_MIN + 1, RB = LONG_MIN",
1415                 .instr = ppc_inst(PPC_RAW_DIVDEU(20, 21, 22)),
1416                 .flags = IGNORE_GPR(20),
1417                 .regs = {
1418                     .gpr[21] = LONG_MIN + 1,
1419                     .gpr[22] = LONG_MIN,
1420                 }
1421             }
1422         }
1423     },
1424     {
1425         .mnemonic = "divdeu.",
1426         .subtests = {
1427             {
1428                 .descr = "RA = LONG_MIN, RB = LONG_MIN",
1429                 .instr = ppc_inst(PPC_RAW_DIVDEU_DOT(20, 21, 22)),
1430                 .flags = IGNORE_GPR(20),
1431                 .regs = {
1432                     .gpr[21] = LONG_MIN,
1433                     .gpr[22] = LONG_MIN,
1434                 }
1435             },
1436             {
1437                 .descr = "RA = 1L, RB = 0",
1438                 .instr = ppc_inst(PPC_RAW_DIVDEU_DOT(20, 21, 22)),
1439                 .flags = IGNORE_GPR(20),
1440                 .regs = {
1441                     .gpr[21] = 1L,
1442                     .gpr[22] = 0,
1443                 }
1444             },
1445             {
1446                 .descr = "RA = LONG_MIN, RB = LONG_MAX",
1447                 .instr = ppc_inst(PPC_RAW_DIVDEU_DOT(20, 21, 22)),
1448                 .regs = {
1449                     .gpr[21] = LONG_MIN,
1450                     .gpr[22] = LONG_MAX,
1451                 }
1452             },
1453             {
1454                 .descr = "RA = LONG_MAX - 1, RB = LONG_MAX",
1455                 .instr = ppc_inst(PPC_RAW_DIVDEU_DOT(20, 21, 22)),
1456                 .regs = {
1457                     .gpr[21] = LONG_MAX - 1,
1458                     .gpr[22] = LONG_MAX,
1459                 }
1460             },
1461             {
1462                 .descr = "RA = LONG_MIN + 1, RB = LONG_MIN",
1463                 .instr = ppc_inst(PPC_RAW_DIVDEU_DOT(20, 21, 22)),
1464                 .flags = IGNORE_GPR(20),
1465                 .regs = {
1466                     .gpr[21] = LONG_MIN + 1,
1467                     .gpr[22] = LONG_MIN,
1468                 }
1469             }
1470         }
1471     },
1472     {
1473         .mnemonic = "paddi",
1474         .cpu_feature = CPU_FTR_ARCH_31,
1475         .subtests = {
1476             {
1477                 .descr = "RA = LONG_MIN, SI = SI_MIN, R = 0",
1478                 .instr = TEST_PADDI(21, 22, SI_MIN, 0),
1479                 .regs = {
1480                     .gpr[21] = 0,
1481                     .gpr[22] = LONG_MIN,
1482                 }
1483             },
1484             {
1485                 .descr = "RA = LONG_MIN, SI = SI_MAX, R = 0",
1486                 .instr = TEST_PADDI(21, 22, SI_MAX, 0),
1487                 .regs = {
1488                     .gpr[21] = 0,
1489                     .gpr[22] = LONG_MIN,
1490                 }
1491             },
1492             {
1493                 .descr = "RA = LONG_MAX, SI = SI_MAX, R = 0",
1494                 .instr = TEST_PADDI(21, 22, SI_MAX, 0),
1495                 .regs = {
1496                     .gpr[21] = 0,
1497                     .gpr[22] = LONG_MAX,
1498                 }
1499             },
1500             {
1501                 .descr = "RA = ULONG_MAX, SI = SI_UMAX, R = 0",
1502                 .instr = TEST_PADDI(21, 22, SI_UMAX, 0),
1503                 .regs = {
1504                     .gpr[21] = 0,
1505                     .gpr[22] = ULONG_MAX,
1506                 }
1507             },
1508             {
1509                 .descr = "RA = ULONG_MAX, SI = 0x1, R = 0",
1510                 .instr = TEST_PADDI(21, 22, 0x1, 0),
1511                 .regs = {
1512                     .gpr[21] = 0,
1513                     .gpr[22] = ULONG_MAX,
1514                 }
1515             },
1516             {
1517                 .descr = "RA = INT_MIN, SI = SI_MIN, R = 0",
1518                 .instr = TEST_PADDI(21, 22, SI_MIN, 0),
1519                 .regs = {
1520                     .gpr[21] = 0,
1521                     .gpr[22] = INT_MIN,
1522                 }
1523             },
1524             {
1525                 .descr = "RA = INT_MIN, SI = SI_MAX, R = 0",
1526                 .instr = TEST_PADDI(21, 22, SI_MAX, 0),
1527                 .regs = {
1528                     .gpr[21] = 0,
1529                     .gpr[22] = INT_MIN,
1530                 }
1531             },
1532             {
1533                 .descr = "RA = INT_MAX, SI = SI_MAX, R = 0",
1534                 .instr = TEST_PADDI(21, 22, SI_MAX, 0),
1535                 .regs = {
1536                     .gpr[21] = 0,
1537                     .gpr[22] = INT_MAX,
1538                 }
1539             },
1540             {
1541                 .descr = "RA = UINT_MAX, SI = 0x1, R = 0",
1542                 .instr = TEST_PADDI(21, 22, 0x1, 0),
1543                 .regs = {
1544                     .gpr[21] = 0,
1545                     .gpr[22] = UINT_MAX,
1546                 }
1547             },
1548             {
1549                 .descr = "RA = UINT_MAX, SI = SI_MAX, R = 0",
1550                 .instr = TEST_PADDI(21, 22, SI_MAX, 0),
1551                 .regs = {
1552                     .gpr[21] = 0,
1553                     .gpr[22] = UINT_MAX,
1554                 }
1555             },
1556             {
1557                 .descr = "RA is r0, SI = SI_MIN, R = 0",
1558                 .instr = TEST_PADDI(21, 0, SI_MIN, 0),
1559                 .regs = {
1560                     .gpr[21] = 0x0,
1561                 }
1562             },
1563             {
1564                 .descr = "RA = 0, SI = SI_MIN, R = 0",
1565                 .instr = TEST_PADDI(21, 22, SI_MIN, 0),
1566                 .regs = {
1567                     .gpr[21] = 0x0,
1568                     .gpr[22] = 0x0,
1569                 }
1570             },
1571             {
1572                 .descr = "RA is r0, SI = 0, R = 1",
1573                 .instr = TEST_PADDI(21, 0, 0, 1),
1574                 .regs = {
1575                     .gpr[21] = 0,
1576                 }
1577             },
1578             {
1579                 .descr = "RA is r0, SI = SI_MIN, R = 1",
1580                 .instr = TEST_PADDI(21, 0, SI_MIN, 1),
1581                 .regs = {
1582                     .gpr[21] = 0,
1583                 }
1584             },
1585             /* Invalid instruction form with R = 1 and RA != 0 */
1586             {
1587                 .descr = "RA = R22(0), SI = 0, R = 1",
1588                 .instr = TEST_PADDI(21, 22, 0, 1),
1589                 .flags = NEGATIVE_TEST,
1590                 .regs = {
1591                     .gpr[21] = 0,
1592                     .gpr[22] = 0,
1593                 }
1594             }
1595         }
1596     }
1597 };
1598 
1599 static int __init emulate_compute_instr(struct pt_regs *regs,
1600                     ppc_inst_t instr,
1601                     bool negative)
1602 {
1603     int analysed;
1604     struct instruction_op op;
1605 
1606     if (!regs || !ppc_inst_val(instr))
1607         return -EINVAL;
1608 
1609     /* This is not a return frame regs */
1610     regs->nip = patch_site_addr(&patch__exec_instr);
1611 
1612     analysed = analyse_instr(&op, regs, instr);
1613     if (analysed != 1 || GETTYPE(op.type) != COMPUTE) {
1614         if (negative)
1615             return -EFAULT;
1616         pr_info("emulation failed, instruction = %08lx\n", ppc_inst_as_ulong(instr));
1617         return -EFAULT;
1618     }
1619     if (analysed == 1 && negative)
1620         pr_info("negative test failed, instruction = %08lx\n", ppc_inst_as_ulong(instr));
1621     if (!negative)
1622         emulate_update_regs(regs, &op);
1623     return 0;
1624 }
1625 
1626 static int __init execute_compute_instr(struct pt_regs *regs,
1627                     ppc_inst_t instr)
1628 {
1629     extern int exec_instr(struct pt_regs *regs);
1630 
1631     if (!regs || !ppc_inst_val(instr))
1632         return -EINVAL;
1633 
1634     /* Patch the NOP with the actual instruction */
1635     patch_instruction_site(&patch__exec_instr, instr);
1636     if (exec_instr(regs)) {
1637         pr_info("execution failed, instruction = %08lx\n", ppc_inst_as_ulong(instr));
1638         return -EFAULT;
1639     }
1640 
1641     return 0;
1642 }
1643 
1644 #define gpr_mismatch(gprn, exp, got)    \
1645     pr_info("GPR%u mismatch, exp = 0x%016lx, got = 0x%016lx\n", \
1646         gprn, exp, got)
1647 
1648 #define reg_mismatch(name, exp, got)    \
1649     pr_info("%s mismatch, exp = 0x%016lx, got = 0x%016lx\n",    \
1650         name, exp, got)
1651 
1652 static void __init run_tests_compute(void)
1653 {
1654     unsigned long flags;
1655     struct compute_test *test;
1656     struct pt_regs *regs, exp, got;
1657     unsigned int i, j, k;
1658     ppc_inst_t instr;
1659     bool ignore_gpr, ignore_xer, ignore_ccr, passed, rc, negative;
1660 
1661     for (i = 0; i < ARRAY_SIZE(compute_tests); i++) {
1662         test = &compute_tests[i];
1663 
1664         if (test->cpu_feature && !early_cpu_has_feature(test->cpu_feature)) {
1665             show_result(test->mnemonic, "SKIP (!CPU_FTR)");
1666             continue;
1667         }
1668 
1669         for (j = 0; j < MAX_SUBTESTS && test->subtests[j].descr; j++) {
1670             instr = test->subtests[j].instr;
1671             flags = test->subtests[j].flags;
1672             regs = &test->subtests[j].regs;
1673             negative = flags & NEGATIVE_TEST;
1674             ignore_xer = flags & IGNORE_XER;
1675             ignore_ccr = flags & IGNORE_CCR;
1676             passed = true;
1677 
1678             memcpy(&exp, regs, sizeof(struct pt_regs));
1679             memcpy(&got, regs, sizeof(struct pt_regs));
1680 
1681             /*
1682              * Set a compatible MSR value explicitly to ensure
1683              * that XER and CR bits are updated appropriately
1684              */
1685             exp.msr = MSR_KERNEL;
1686             got.msr = MSR_KERNEL;
1687 
1688             rc = emulate_compute_instr(&got, instr, negative) != 0;
1689             if (negative) {
1690                 /* skip executing instruction */
1691                 passed = rc;
1692                 goto print;
1693             } else if (rc || execute_compute_instr(&exp, instr)) {
1694                 passed = false;
1695                 goto print;
1696             }
1697 
1698             /* Verify GPR values */
1699             for (k = 0; k < 32; k++) {
1700                 ignore_gpr = flags & IGNORE_GPR(k);
1701                 if (!ignore_gpr && exp.gpr[k] != got.gpr[k]) {
1702                     passed = false;
1703                     gpr_mismatch(k, exp.gpr[k], got.gpr[k]);
1704                 }
1705             }
1706 
1707             /* Verify LR value */
1708             if (exp.link != got.link) {
1709                 passed = false;
1710                 reg_mismatch("LR", exp.link, got.link);
1711             }
1712 
1713             /* Verify XER value */
1714             if (!ignore_xer && exp.xer != got.xer) {
1715                 passed = false;
1716                 reg_mismatch("XER", exp.xer, got.xer);
1717             }
1718 
1719             /* Verify CR value */
1720             if (!ignore_ccr && exp.ccr != got.ccr) {
1721                 passed = false;
1722                 reg_mismatch("CR", exp.ccr, got.ccr);
1723             }
1724 
1725 print:
1726             show_result_with_descr(test->mnemonic,
1727                            test->subtests[j].descr,
1728                            passed ? "PASS" : "FAIL");
1729         }
1730     }
1731 }
1732 
1733 static int __init test_emulate_step(void)
1734 {
1735     printk(KERN_INFO "Running instruction emulation self-tests ...\n");
1736     run_tests_load_store();
1737     run_tests_compute();
1738 
1739     return 0;
1740 }
1741 late_initcall(test_emulate_step);