12874c5fdSThomas Gleixner // SPDX-License-Identifier: GPL-2.0-or-later 24ceae137SRavi Bangoria /* 384022ac1SSandipan Das * Simple sanity tests for instruction emulation infrastructure. 44ceae137SRavi Bangoria * 54ceae137SRavi Bangoria * Copyright IBM Corp. 2016 64ceae137SRavi Bangoria */ 74ceae137SRavi Bangoria 84ceae137SRavi Bangoria #define pr_fmt(fmt) "emulate_step_test: " fmt 94ceae137SRavi Bangoria 104ceae137SRavi Bangoria #include <linux/ptrace.h> 114ceae137SRavi Bangoria #include <asm/sstep.h> 124ceae137SRavi Bangoria #include <asm/ppc-opcode.h> 1384022ac1SSandipan Das #include <asm/code-patching.h> 1475346251SJordan Niethe #include <asm/inst.h> 154ceae137SRavi Bangoria 1684022ac1SSandipan Das #define MAX_SUBTESTS 16 1784022ac1SSandipan Das 1884022ac1SSandipan Das #define IGNORE_GPR(n) (0x1UL << (n)) 1984022ac1SSandipan Das #define IGNORE_XER (0x1UL << 32) 2084022ac1SSandipan Das #define IGNORE_CCR (0x1UL << 33) 214ceae137SRavi Bangoria 224ceae137SRavi Bangoria static void __init init_pt_regs(struct pt_regs *regs) 234ceae137SRavi Bangoria { 244ceae137SRavi Bangoria static unsigned long msr; 254ceae137SRavi Bangoria static bool msr_cached; 264ceae137SRavi Bangoria 274ceae137SRavi Bangoria memset(regs, 0, sizeof(struct pt_regs)); 284ceae137SRavi Bangoria 294ceae137SRavi Bangoria if (likely(msr_cached)) { 304ceae137SRavi Bangoria regs->msr = msr; 314ceae137SRavi Bangoria return; 324ceae137SRavi Bangoria } 334ceae137SRavi Bangoria 344ceae137SRavi Bangoria asm volatile("mfmsr %0" : "=r"(regs->msr)); 354ceae137SRavi Bangoria 364ceae137SRavi Bangoria regs->msr |= MSR_FP; 374ceae137SRavi Bangoria regs->msr |= MSR_VEC; 384ceae137SRavi Bangoria regs->msr |= MSR_VSX; 394ceae137SRavi Bangoria 404ceae137SRavi Bangoria msr = regs->msr; 414ceae137SRavi Bangoria msr_cached = true; 424ceae137SRavi Bangoria } 434ceae137SRavi Bangoria 4484022ac1SSandipan Das static void __init show_result(char *mnemonic, char *result) 454ceae137SRavi Bangoria { 4684022ac1SSandipan Das pr_info("%-14s : %s\n", mnemonic, result); 4784022ac1SSandipan Das } 4884022ac1SSandipan Das 4984022ac1SSandipan Das static void __init show_result_with_descr(char *mnemonic, char *descr, 5084022ac1SSandipan Das char *result) 5184022ac1SSandipan Das { 5284022ac1SSandipan Das pr_info("%-14s : %-50s %s\n", mnemonic, descr, result); 534ceae137SRavi Bangoria } 544ceae137SRavi Bangoria 554ceae137SRavi Bangoria static void __init test_ld(void) 564ceae137SRavi Bangoria { 574ceae137SRavi Bangoria struct pt_regs regs; 584ceae137SRavi Bangoria unsigned long a = 0x23; 594ceae137SRavi Bangoria int stepped = -1; 604ceae137SRavi Bangoria 614ceae137SRavi Bangoria init_pt_regs(®s); 624ceae137SRavi Bangoria regs.gpr[3] = (unsigned long) &a; 634ceae137SRavi Bangoria 644ceae137SRavi Bangoria /* ld r5, 0(r3) */ 65*1d33dd84SBalamuruhan S stepped = emulate_step(®s, ppc_inst(PPC_RAW_LD(5, 3, 0))); 664ceae137SRavi Bangoria 674ceae137SRavi Bangoria if (stepped == 1 && regs.gpr[5] == a) 684ceae137SRavi Bangoria show_result("ld", "PASS"); 694ceae137SRavi Bangoria else 704ceae137SRavi Bangoria show_result("ld", "FAIL"); 714ceae137SRavi Bangoria } 724ceae137SRavi Bangoria 734ceae137SRavi Bangoria static void __init test_lwz(void) 744ceae137SRavi Bangoria { 754ceae137SRavi Bangoria struct pt_regs regs; 764ceae137SRavi Bangoria unsigned int a = 0x4545; 774ceae137SRavi Bangoria int stepped = -1; 784ceae137SRavi Bangoria 794ceae137SRavi Bangoria init_pt_regs(®s); 804ceae137SRavi Bangoria regs.gpr[3] = (unsigned long) &a; 814ceae137SRavi Bangoria 824ceae137SRavi Bangoria /* lwz r5, 0(r3) */ 83*1d33dd84SBalamuruhan S stepped = emulate_step(®s, ppc_inst(PPC_RAW_LWZ(5, 3, 0))); 844ceae137SRavi Bangoria 854ceae137SRavi Bangoria if (stepped == 1 && regs.gpr[5] == a) 864ceae137SRavi Bangoria show_result("lwz", "PASS"); 874ceae137SRavi Bangoria else 884ceae137SRavi Bangoria show_result("lwz", "FAIL"); 894ceae137SRavi Bangoria } 904ceae137SRavi Bangoria 914ceae137SRavi Bangoria static void __init test_lwzx(void) 924ceae137SRavi Bangoria { 934ceae137SRavi Bangoria struct pt_regs regs; 944ceae137SRavi Bangoria unsigned int a[3] = {0x0, 0x0, 0x1234}; 954ceae137SRavi Bangoria int stepped = -1; 964ceae137SRavi Bangoria 974ceae137SRavi Bangoria init_pt_regs(®s); 984ceae137SRavi Bangoria regs.gpr[3] = (unsigned long) a; 994ceae137SRavi Bangoria regs.gpr[4] = 8; 1004ceae137SRavi Bangoria regs.gpr[5] = 0x8765; 1014ceae137SRavi Bangoria 1024ceae137SRavi Bangoria /* lwzx r5, r3, r4 */ 103*1d33dd84SBalamuruhan S stepped = emulate_step(®s, ppc_inst(PPC_RAW_LWZX(5, 3, 4))); 1044ceae137SRavi Bangoria if (stepped == 1 && regs.gpr[5] == a[2]) 1054ceae137SRavi Bangoria show_result("lwzx", "PASS"); 1064ceae137SRavi Bangoria else 1074ceae137SRavi Bangoria show_result("lwzx", "FAIL"); 1084ceae137SRavi Bangoria } 1094ceae137SRavi Bangoria 1104ceae137SRavi Bangoria static void __init test_std(void) 1114ceae137SRavi Bangoria { 1124ceae137SRavi Bangoria struct pt_regs regs; 1134ceae137SRavi Bangoria unsigned long a = 0x1234; 1144ceae137SRavi Bangoria int stepped = -1; 1154ceae137SRavi Bangoria 1164ceae137SRavi Bangoria init_pt_regs(®s); 1174ceae137SRavi Bangoria regs.gpr[3] = (unsigned long) &a; 1184ceae137SRavi Bangoria regs.gpr[5] = 0x5678; 1194ceae137SRavi Bangoria 1204ceae137SRavi Bangoria /* std r5, 0(r3) */ 121*1d33dd84SBalamuruhan S stepped = emulate_step(®s, ppc_inst(PPC_RAW_STD(5, 3, 0))); 12259ed2adfSNicholas Piggin if (stepped == 1 && regs.gpr[5] == a) 1234ceae137SRavi Bangoria show_result("std", "PASS"); 1244ceae137SRavi Bangoria else 1254ceae137SRavi Bangoria show_result("std", "FAIL"); 1264ceae137SRavi Bangoria } 1274ceae137SRavi Bangoria 1284ceae137SRavi Bangoria static void __init test_ldarx_stdcx(void) 1294ceae137SRavi Bangoria { 1304ceae137SRavi Bangoria struct pt_regs regs; 1314ceae137SRavi Bangoria unsigned long a = 0x1234; 1324ceae137SRavi Bangoria int stepped = -1; 1334ceae137SRavi Bangoria unsigned long cr0_eq = 0x1 << 29; /* eq bit of CR0 */ 1344ceae137SRavi Bangoria 1354ceae137SRavi Bangoria init_pt_regs(®s); 1364ceae137SRavi Bangoria asm volatile("mfcr %0" : "=r"(regs.ccr)); 1374ceae137SRavi Bangoria 1384ceae137SRavi Bangoria 1394ceae137SRavi Bangoria /*** ldarx ***/ 1404ceae137SRavi Bangoria 1414ceae137SRavi Bangoria regs.gpr[3] = (unsigned long) &a; 1424ceae137SRavi Bangoria regs.gpr[4] = 0; 1434ceae137SRavi Bangoria regs.gpr[5] = 0x5678; 1444ceae137SRavi Bangoria 1454ceae137SRavi Bangoria /* ldarx r5, r3, r4, 0 */ 146*1d33dd84SBalamuruhan S stepped = emulate_step(®s, ppc_inst(PPC_RAW_LDARX(5, 3, 4, 0))); 1474ceae137SRavi Bangoria 1484ceae137SRavi Bangoria /* 1494ceae137SRavi Bangoria * Don't touch 'a' here. Touching 'a' can do Load/store 1504ceae137SRavi Bangoria * of 'a' which result in failure of subsequent stdcx. 1514ceae137SRavi Bangoria * Instead, use hardcoded value for comparison. 1524ceae137SRavi Bangoria */ 1534ceae137SRavi Bangoria if (stepped <= 0 || regs.gpr[5] != 0x1234) { 1544ceae137SRavi Bangoria show_result("ldarx / stdcx.", "FAIL (ldarx)"); 1554ceae137SRavi Bangoria return; 1564ceae137SRavi Bangoria } 1574ceae137SRavi Bangoria 1584ceae137SRavi Bangoria 1594ceae137SRavi Bangoria /*** stdcx. ***/ 1604ceae137SRavi Bangoria 1614ceae137SRavi Bangoria regs.gpr[5] = 0x9ABC; 1624ceae137SRavi Bangoria 1634ceae137SRavi Bangoria /* stdcx. r5, r3, r4 */ 164*1d33dd84SBalamuruhan S stepped = emulate_step(®s, ppc_inst(PPC_RAW_STDCX(5, 3, 4))); 1654ceae137SRavi Bangoria 1664ceae137SRavi Bangoria /* 1674ceae137SRavi Bangoria * Two possible scenarios that indicates successful emulation 1684ceae137SRavi Bangoria * of stdcx. : 1694ceae137SRavi Bangoria * 1. Reservation is active and store is performed. In this 1704ceae137SRavi Bangoria * case cr0.eq bit will be set to 1. 1714ceae137SRavi Bangoria * 2. Reservation is not active and store is not performed. 1724ceae137SRavi Bangoria * In this case cr0.eq bit will be set to 0. 1734ceae137SRavi Bangoria */ 1744ceae137SRavi Bangoria if (stepped == 1 && ((regs.gpr[5] == a && (regs.ccr & cr0_eq)) 1754ceae137SRavi Bangoria || (regs.gpr[5] != a && !(regs.ccr & cr0_eq)))) 1764ceae137SRavi Bangoria show_result("ldarx / stdcx.", "PASS"); 1774ceae137SRavi Bangoria else 1784ceae137SRavi Bangoria show_result("ldarx / stdcx.", "FAIL (stdcx.)"); 1794ceae137SRavi Bangoria } 1804ceae137SRavi Bangoria 1814ceae137SRavi Bangoria #ifdef CONFIG_PPC_FPU 1824ceae137SRavi Bangoria static void __init test_lfsx_stfsx(void) 1834ceae137SRavi Bangoria { 1844ceae137SRavi Bangoria struct pt_regs regs; 1854ceae137SRavi Bangoria union { 1864ceae137SRavi Bangoria float a; 1874ceae137SRavi Bangoria int b; 1884ceae137SRavi Bangoria } c; 1894ceae137SRavi Bangoria int cached_b; 1904ceae137SRavi Bangoria int stepped = -1; 1914ceae137SRavi Bangoria 1924ceae137SRavi Bangoria init_pt_regs(®s); 1934ceae137SRavi Bangoria 1944ceae137SRavi Bangoria 1954ceae137SRavi Bangoria /*** lfsx ***/ 1964ceae137SRavi Bangoria 1974ceae137SRavi Bangoria c.a = 123.45; 1984ceae137SRavi Bangoria cached_b = c.b; 1994ceae137SRavi Bangoria 2004ceae137SRavi Bangoria regs.gpr[3] = (unsigned long) &c.a; 2014ceae137SRavi Bangoria regs.gpr[4] = 0; 2024ceae137SRavi Bangoria 2034ceae137SRavi Bangoria /* lfsx frt10, r3, r4 */ 204*1d33dd84SBalamuruhan S stepped = emulate_step(®s, ppc_inst(PPC_RAW_LFSX(10, 3, 4))); 2054ceae137SRavi Bangoria 2064ceae137SRavi Bangoria if (stepped == 1) 2074ceae137SRavi Bangoria show_result("lfsx", "PASS"); 2084ceae137SRavi Bangoria else 2094ceae137SRavi Bangoria show_result("lfsx", "FAIL"); 2104ceae137SRavi Bangoria 2114ceae137SRavi Bangoria 2124ceae137SRavi Bangoria /*** stfsx ***/ 2134ceae137SRavi Bangoria 2144ceae137SRavi Bangoria c.a = 678.91; 2154ceae137SRavi Bangoria 2164ceae137SRavi Bangoria /* stfsx frs10, r3, r4 */ 217*1d33dd84SBalamuruhan S stepped = emulate_step(®s, ppc_inst(PPC_RAW_STFSX(10, 3, 4))); 2184ceae137SRavi Bangoria 2194ceae137SRavi Bangoria if (stepped == 1 && c.b == cached_b) 2204ceae137SRavi Bangoria show_result("stfsx", "PASS"); 2214ceae137SRavi Bangoria else 2224ceae137SRavi Bangoria show_result("stfsx", "FAIL"); 2234ceae137SRavi Bangoria } 2244ceae137SRavi Bangoria 2254ceae137SRavi Bangoria static void __init test_lfdx_stfdx(void) 2264ceae137SRavi Bangoria { 2274ceae137SRavi Bangoria struct pt_regs regs; 2284ceae137SRavi Bangoria union { 2294ceae137SRavi Bangoria double a; 2304ceae137SRavi Bangoria long b; 2314ceae137SRavi Bangoria } c; 2324ceae137SRavi Bangoria long cached_b; 2334ceae137SRavi Bangoria int stepped = -1; 2344ceae137SRavi Bangoria 2354ceae137SRavi Bangoria init_pt_regs(®s); 2364ceae137SRavi Bangoria 2374ceae137SRavi Bangoria 2384ceae137SRavi Bangoria /*** lfdx ***/ 2394ceae137SRavi Bangoria 2404ceae137SRavi Bangoria c.a = 123456.78; 2414ceae137SRavi Bangoria cached_b = c.b; 2424ceae137SRavi Bangoria 2434ceae137SRavi Bangoria regs.gpr[3] = (unsigned long) &c.a; 2444ceae137SRavi Bangoria regs.gpr[4] = 0; 2454ceae137SRavi Bangoria 2464ceae137SRavi Bangoria /* lfdx frt10, r3, r4 */ 247*1d33dd84SBalamuruhan S stepped = emulate_step(®s, ppc_inst(PPC_RAW_LFDX(10, 3, 4))); 2484ceae137SRavi Bangoria 2494ceae137SRavi Bangoria if (stepped == 1) 2504ceae137SRavi Bangoria show_result("lfdx", "PASS"); 2514ceae137SRavi Bangoria else 2524ceae137SRavi Bangoria show_result("lfdx", "FAIL"); 2534ceae137SRavi Bangoria 2544ceae137SRavi Bangoria 2554ceae137SRavi Bangoria /*** stfdx ***/ 2564ceae137SRavi Bangoria 2574ceae137SRavi Bangoria c.a = 987654.32; 2584ceae137SRavi Bangoria 2594ceae137SRavi Bangoria /* stfdx frs10, r3, r4 */ 260*1d33dd84SBalamuruhan S stepped = emulate_step(®s, ppc_inst(PPC_RAW_STFDX(10, 3, 4))); 2614ceae137SRavi Bangoria 2624ceae137SRavi Bangoria if (stepped == 1 && c.b == cached_b) 2634ceae137SRavi Bangoria show_result("stfdx", "PASS"); 2644ceae137SRavi Bangoria else 2654ceae137SRavi Bangoria show_result("stfdx", "FAIL"); 2664ceae137SRavi Bangoria } 2674ceae137SRavi Bangoria #else 2684ceae137SRavi Bangoria static void __init test_lfsx_stfsx(void) 2694ceae137SRavi Bangoria { 2704ceae137SRavi Bangoria show_result("lfsx", "SKIP (CONFIG_PPC_FPU is not set)"); 2714ceae137SRavi Bangoria show_result("stfsx", "SKIP (CONFIG_PPC_FPU is not set)"); 2724ceae137SRavi Bangoria } 2734ceae137SRavi Bangoria 2744ceae137SRavi Bangoria static void __init test_lfdx_stfdx(void) 2754ceae137SRavi Bangoria { 2764ceae137SRavi Bangoria show_result("lfdx", "SKIP (CONFIG_PPC_FPU is not set)"); 2774ceae137SRavi Bangoria show_result("stfdx", "SKIP (CONFIG_PPC_FPU is not set)"); 2784ceae137SRavi Bangoria } 2794ceae137SRavi Bangoria #endif /* CONFIG_PPC_FPU */ 2804ceae137SRavi Bangoria 2814ceae137SRavi Bangoria #ifdef CONFIG_ALTIVEC 2824ceae137SRavi Bangoria static void __init test_lvx_stvx(void) 2834ceae137SRavi Bangoria { 2844ceae137SRavi Bangoria struct pt_regs regs; 2854ceae137SRavi Bangoria union { 2864ceae137SRavi Bangoria vector128 a; 2874ceae137SRavi Bangoria u32 b[4]; 2884ceae137SRavi Bangoria } c; 2894ceae137SRavi Bangoria u32 cached_b[4]; 2904ceae137SRavi Bangoria int stepped = -1; 2914ceae137SRavi Bangoria 2924ceae137SRavi Bangoria init_pt_regs(®s); 2934ceae137SRavi Bangoria 2944ceae137SRavi Bangoria 2954ceae137SRavi Bangoria /*** lvx ***/ 2964ceae137SRavi Bangoria 2974ceae137SRavi Bangoria cached_b[0] = c.b[0] = 923745; 2984ceae137SRavi Bangoria cached_b[1] = c.b[1] = 2139478; 2994ceae137SRavi Bangoria cached_b[2] = c.b[2] = 9012; 3004ceae137SRavi Bangoria cached_b[3] = c.b[3] = 982134; 3014ceae137SRavi Bangoria 3024ceae137SRavi Bangoria regs.gpr[3] = (unsigned long) &c.a; 3034ceae137SRavi Bangoria regs.gpr[4] = 0; 3044ceae137SRavi Bangoria 3054ceae137SRavi Bangoria /* lvx vrt10, r3, r4 */ 306*1d33dd84SBalamuruhan S stepped = emulate_step(®s, ppc_inst(PPC_RAW_LVX(10, 3, 4))); 3074ceae137SRavi Bangoria 3084ceae137SRavi Bangoria if (stepped == 1) 3094ceae137SRavi Bangoria show_result("lvx", "PASS"); 3104ceae137SRavi Bangoria else 3114ceae137SRavi Bangoria show_result("lvx", "FAIL"); 3124ceae137SRavi Bangoria 3134ceae137SRavi Bangoria 3144ceae137SRavi Bangoria /*** stvx ***/ 3154ceae137SRavi Bangoria 3164ceae137SRavi Bangoria c.b[0] = 4987513; 3174ceae137SRavi Bangoria c.b[1] = 84313948; 3184ceae137SRavi Bangoria c.b[2] = 71; 3194ceae137SRavi Bangoria c.b[3] = 498532; 3204ceae137SRavi Bangoria 3214ceae137SRavi Bangoria /* stvx vrs10, r3, r4 */ 322*1d33dd84SBalamuruhan S stepped = emulate_step(®s, ppc_inst(PPC_RAW_STVX(10, 3, 4))); 3234ceae137SRavi Bangoria 3244ceae137SRavi Bangoria if (stepped == 1 && cached_b[0] == c.b[0] && cached_b[1] == c.b[1] && 3254ceae137SRavi Bangoria cached_b[2] == c.b[2] && cached_b[3] == c.b[3]) 3264ceae137SRavi Bangoria show_result("stvx", "PASS"); 3274ceae137SRavi Bangoria else 3284ceae137SRavi Bangoria show_result("stvx", "FAIL"); 3294ceae137SRavi Bangoria } 3304ceae137SRavi Bangoria #else 3314ceae137SRavi Bangoria static void __init test_lvx_stvx(void) 3324ceae137SRavi Bangoria { 3334ceae137SRavi Bangoria show_result("lvx", "SKIP (CONFIG_ALTIVEC is not set)"); 3344ceae137SRavi Bangoria show_result("stvx", "SKIP (CONFIG_ALTIVEC is not set)"); 3354ceae137SRavi Bangoria } 3364ceae137SRavi Bangoria #endif /* CONFIG_ALTIVEC */ 3374ceae137SRavi Bangoria 3384ceae137SRavi Bangoria #ifdef CONFIG_VSX 3394ceae137SRavi Bangoria static void __init test_lxvd2x_stxvd2x(void) 3404ceae137SRavi Bangoria { 3414ceae137SRavi Bangoria struct pt_regs regs; 3424ceae137SRavi Bangoria union { 3434ceae137SRavi Bangoria vector128 a; 3444ceae137SRavi Bangoria u32 b[4]; 3454ceae137SRavi Bangoria } c; 3464ceae137SRavi Bangoria u32 cached_b[4]; 3474ceae137SRavi Bangoria int stepped = -1; 3484ceae137SRavi Bangoria 3494ceae137SRavi Bangoria init_pt_regs(®s); 3504ceae137SRavi Bangoria 3514ceae137SRavi Bangoria 3524ceae137SRavi Bangoria /*** lxvd2x ***/ 3534ceae137SRavi Bangoria 3544ceae137SRavi Bangoria cached_b[0] = c.b[0] = 18233; 3554ceae137SRavi Bangoria cached_b[1] = c.b[1] = 34863571; 3564ceae137SRavi Bangoria cached_b[2] = c.b[2] = 834; 3574ceae137SRavi Bangoria cached_b[3] = c.b[3] = 6138911; 3584ceae137SRavi Bangoria 3594ceae137SRavi Bangoria regs.gpr[3] = (unsigned long) &c.a; 3604ceae137SRavi Bangoria regs.gpr[4] = 0; 3614ceae137SRavi Bangoria 3624ceae137SRavi Bangoria /* lxvd2x vsr39, r3, r4 */ 363*1d33dd84SBalamuruhan S stepped = emulate_step(®s, ppc_inst(PPC_RAW_LXVD2X(39, R3, R4))); 3644ceae137SRavi Bangoria 3655a61640eSRavi Bangoria if (stepped == 1 && cpu_has_feature(CPU_FTR_VSX)) { 3664ceae137SRavi Bangoria show_result("lxvd2x", "PASS"); 3675a61640eSRavi Bangoria } else { 3685a61640eSRavi Bangoria if (!cpu_has_feature(CPU_FTR_VSX)) 3695a61640eSRavi Bangoria show_result("lxvd2x", "PASS (!CPU_FTR_VSX)"); 3704ceae137SRavi Bangoria else 3714ceae137SRavi Bangoria show_result("lxvd2x", "FAIL"); 3725a61640eSRavi Bangoria } 3734ceae137SRavi Bangoria 3744ceae137SRavi Bangoria 3754ceae137SRavi Bangoria /*** stxvd2x ***/ 3764ceae137SRavi Bangoria 3774ceae137SRavi Bangoria c.b[0] = 21379463; 3784ceae137SRavi Bangoria c.b[1] = 87; 3794ceae137SRavi Bangoria c.b[2] = 374234; 3804ceae137SRavi Bangoria c.b[3] = 4; 3814ceae137SRavi Bangoria 3824ceae137SRavi Bangoria /* stxvd2x vsr39, r3, r4 */ 383*1d33dd84SBalamuruhan S stepped = emulate_step(®s, ppc_inst(PPC_RAW_STXVD2X(39, R3, R4))); 3844ceae137SRavi Bangoria 3854ceae137SRavi Bangoria if (stepped == 1 && cached_b[0] == c.b[0] && cached_b[1] == c.b[1] && 3865a61640eSRavi Bangoria cached_b[2] == c.b[2] && cached_b[3] == c.b[3] && 3875a61640eSRavi Bangoria cpu_has_feature(CPU_FTR_VSX)) { 3884ceae137SRavi Bangoria show_result("stxvd2x", "PASS"); 3895a61640eSRavi Bangoria } else { 3905a61640eSRavi Bangoria if (!cpu_has_feature(CPU_FTR_VSX)) 3915a61640eSRavi Bangoria show_result("stxvd2x", "PASS (!CPU_FTR_VSX)"); 3924ceae137SRavi Bangoria else 3934ceae137SRavi Bangoria show_result("stxvd2x", "FAIL"); 3944ceae137SRavi Bangoria } 3955a61640eSRavi Bangoria } 3964ceae137SRavi Bangoria #else 3974ceae137SRavi Bangoria static void __init test_lxvd2x_stxvd2x(void) 3984ceae137SRavi Bangoria { 3994ceae137SRavi Bangoria show_result("lxvd2x", "SKIP (CONFIG_VSX is not set)"); 4004ceae137SRavi Bangoria show_result("stxvd2x", "SKIP (CONFIG_VSX is not set)"); 4014ceae137SRavi Bangoria } 4024ceae137SRavi Bangoria #endif /* CONFIG_VSX */ 4034ceae137SRavi Bangoria 40484022ac1SSandipan Das static void __init run_tests_load_store(void) 4054ceae137SRavi Bangoria { 4064ceae137SRavi Bangoria test_ld(); 4074ceae137SRavi Bangoria test_lwz(); 4084ceae137SRavi Bangoria test_lwzx(); 4094ceae137SRavi Bangoria test_std(); 4104ceae137SRavi Bangoria test_ldarx_stdcx(); 4114ceae137SRavi Bangoria test_lfsx_stfsx(); 4124ceae137SRavi Bangoria test_lfdx_stfdx(); 4134ceae137SRavi Bangoria test_lvx_stvx(); 4144ceae137SRavi Bangoria test_lxvd2x_stxvd2x(); 41584022ac1SSandipan Das } 41684022ac1SSandipan Das 41784022ac1SSandipan Das struct compute_test { 41884022ac1SSandipan Das char *mnemonic; 41984022ac1SSandipan Das struct { 42084022ac1SSandipan Das char *descr; 42184022ac1SSandipan Das unsigned long flags; 42294afd069SJordan Niethe struct ppc_inst instr; 42384022ac1SSandipan Das struct pt_regs regs; 42484022ac1SSandipan Das } subtests[MAX_SUBTESTS + 1]; 42584022ac1SSandipan Das }; 42684022ac1SSandipan Das 42784022ac1SSandipan Das static struct compute_test compute_tests[] = { 42884022ac1SSandipan Das { 42984022ac1SSandipan Das .mnemonic = "nop", 43084022ac1SSandipan Das .subtests = { 43184022ac1SSandipan Das { 43284022ac1SSandipan Das .descr = "R0 = LONG_MAX", 43375346251SJordan Niethe .instr = ppc_inst(PPC_INST_NOP), 43484022ac1SSandipan Das .regs = { 43584022ac1SSandipan Das .gpr[0] = LONG_MAX, 43684022ac1SSandipan Das } 43784022ac1SSandipan Das } 43884022ac1SSandipan Das } 43944dea178SSandipan Das }, 44044dea178SSandipan Das { 44144dea178SSandipan Das .mnemonic = "add", 44244dea178SSandipan Das .subtests = { 44344dea178SSandipan Das { 44444dea178SSandipan Das .descr = "RA = LONG_MIN, RB = LONG_MIN", 445*1d33dd84SBalamuruhan S .instr = ppc_inst(PPC_RAW_ADD(20, 21, 22)), 44644dea178SSandipan Das .regs = { 44744dea178SSandipan Das .gpr[21] = LONG_MIN, 44844dea178SSandipan Das .gpr[22] = LONG_MIN, 44944dea178SSandipan Das } 45044dea178SSandipan Das }, 45144dea178SSandipan Das { 45244dea178SSandipan Das .descr = "RA = LONG_MIN, RB = LONG_MAX", 453*1d33dd84SBalamuruhan S .instr = ppc_inst(PPC_RAW_ADD(20, 21, 22)), 45444dea178SSandipan Das .regs = { 45544dea178SSandipan Das .gpr[21] = LONG_MIN, 45644dea178SSandipan Das .gpr[22] = LONG_MAX, 45744dea178SSandipan Das } 45844dea178SSandipan Das }, 45944dea178SSandipan Das { 46044dea178SSandipan Das .descr = "RA = LONG_MAX, RB = LONG_MAX", 461*1d33dd84SBalamuruhan S .instr = ppc_inst(PPC_RAW_ADD(20, 21, 22)), 46244dea178SSandipan Das .regs = { 46344dea178SSandipan Das .gpr[21] = LONG_MAX, 46444dea178SSandipan Das .gpr[22] = LONG_MAX, 46544dea178SSandipan Das } 46644dea178SSandipan Das }, 46744dea178SSandipan Das { 46844dea178SSandipan Das .descr = "RA = ULONG_MAX, RB = ULONG_MAX", 469*1d33dd84SBalamuruhan S .instr = ppc_inst(PPC_RAW_ADD(20, 21, 22)), 47044dea178SSandipan Das .regs = { 47144dea178SSandipan Das .gpr[21] = ULONG_MAX, 47244dea178SSandipan Das .gpr[22] = ULONG_MAX, 47344dea178SSandipan Das } 47444dea178SSandipan Das }, 47544dea178SSandipan Das { 47644dea178SSandipan Das .descr = "RA = ULONG_MAX, RB = 0x1", 477*1d33dd84SBalamuruhan S .instr = ppc_inst(PPC_RAW_ADD(20, 21, 22)), 47844dea178SSandipan Das .regs = { 47944dea178SSandipan Das .gpr[21] = ULONG_MAX, 48044dea178SSandipan Das .gpr[22] = 0x1, 48144dea178SSandipan Das } 48244dea178SSandipan Das }, 48344dea178SSandipan Das { 48444dea178SSandipan Das .descr = "RA = INT_MIN, RB = INT_MIN", 485*1d33dd84SBalamuruhan S .instr = ppc_inst(PPC_RAW_ADD(20, 21, 22)), 48644dea178SSandipan Das .regs = { 48744dea178SSandipan Das .gpr[21] = INT_MIN, 48844dea178SSandipan Das .gpr[22] = INT_MIN, 48944dea178SSandipan Das } 49044dea178SSandipan Das }, 49144dea178SSandipan Das { 49244dea178SSandipan Das .descr = "RA = INT_MIN, RB = INT_MAX", 493*1d33dd84SBalamuruhan S .instr = ppc_inst(PPC_RAW_ADD(20, 21, 22)), 49444dea178SSandipan Das .regs = { 49544dea178SSandipan Das .gpr[21] = INT_MIN, 49644dea178SSandipan Das .gpr[22] = INT_MAX, 49744dea178SSandipan Das } 49844dea178SSandipan Das }, 49944dea178SSandipan Das { 50044dea178SSandipan Das .descr = "RA = INT_MAX, RB = INT_MAX", 501*1d33dd84SBalamuruhan S .instr = ppc_inst(PPC_RAW_ADD(20, 21, 22)), 50244dea178SSandipan Das .regs = { 50344dea178SSandipan Das .gpr[21] = INT_MAX, 50444dea178SSandipan Das .gpr[22] = INT_MAX, 50544dea178SSandipan Das } 50644dea178SSandipan Das }, 50744dea178SSandipan Das { 50844dea178SSandipan Das .descr = "RA = UINT_MAX, RB = UINT_MAX", 509*1d33dd84SBalamuruhan S .instr = ppc_inst(PPC_RAW_ADD(20, 21, 22)), 51044dea178SSandipan Das .regs = { 51144dea178SSandipan Das .gpr[21] = UINT_MAX, 51244dea178SSandipan Das .gpr[22] = UINT_MAX, 51344dea178SSandipan Das } 51444dea178SSandipan Das }, 51544dea178SSandipan Das { 51644dea178SSandipan Das .descr = "RA = UINT_MAX, RB = 0x1", 517*1d33dd84SBalamuruhan S .instr = ppc_inst(PPC_RAW_ADD(20, 21, 22)), 51844dea178SSandipan Das .regs = { 51944dea178SSandipan Das .gpr[21] = UINT_MAX, 52044dea178SSandipan Das .gpr[22] = 0x1, 52144dea178SSandipan Das } 52244dea178SSandipan Das } 52344dea178SSandipan Das } 52444dea178SSandipan Das }, 52544dea178SSandipan Das { 52644dea178SSandipan Das .mnemonic = "add.", 52744dea178SSandipan Das .subtests = { 52844dea178SSandipan Das { 52944dea178SSandipan Das .descr = "RA = LONG_MIN, RB = LONG_MIN", 53044dea178SSandipan Das .flags = IGNORE_CCR, 531*1d33dd84SBalamuruhan S .instr = ppc_inst(PPC_RAW_ADD_DOT(20, 21, 22)), 53244dea178SSandipan Das .regs = { 53344dea178SSandipan Das .gpr[21] = LONG_MIN, 53444dea178SSandipan Das .gpr[22] = LONG_MIN, 53544dea178SSandipan Das } 53644dea178SSandipan Das }, 53744dea178SSandipan Das { 53844dea178SSandipan Das .descr = "RA = LONG_MIN, RB = LONG_MAX", 539*1d33dd84SBalamuruhan S .instr = ppc_inst(PPC_RAW_ADD_DOT(20, 21, 22)), 54044dea178SSandipan Das .regs = { 54144dea178SSandipan Das .gpr[21] = LONG_MIN, 54244dea178SSandipan Das .gpr[22] = LONG_MAX, 54344dea178SSandipan Das } 54444dea178SSandipan Das }, 54544dea178SSandipan Das { 54644dea178SSandipan Das .descr = "RA = LONG_MAX, RB = LONG_MAX", 54744dea178SSandipan Das .flags = IGNORE_CCR, 548*1d33dd84SBalamuruhan S .instr = ppc_inst(PPC_RAW_ADD_DOT(20, 21, 22)), 54944dea178SSandipan Das .regs = { 55044dea178SSandipan Das .gpr[21] = LONG_MAX, 55144dea178SSandipan Das .gpr[22] = LONG_MAX, 55244dea178SSandipan Das } 55344dea178SSandipan Das }, 55444dea178SSandipan Das { 55544dea178SSandipan Das .descr = "RA = ULONG_MAX, RB = ULONG_MAX", 556*1d33dd84SBalamuruhan S .instr = ppc_inst(PPC_RAW_ADD_DOT(20, 21, 22)), 55744dea178SSandipan Das .regs = { 55844dea178SSandipan Das .gpr[21] = ULONG_MAX, 55944dea178SSandipan Das .gpr[22] = ULONG_MAX, 56044dea178SSandipan Das } 56144dea178SSandipan Das }, 56244dea178SSandipan Das { 56344dea178SSandipan Das .descr = "RA = ULONG_MAX, RB = 0x1", 564*1d33dd84SBalamuruhan S .instr = ppc_inst(PPC_RAW_ADD_DOT(20, 21, 22)), 56544dea178SSandipan Das .regs = { 56644dea178SSandipan Das .gpr[21] = ULONG_MAX, 56744dea178SSandipan Das .gpr[22] = 0x1, 56844dea178SSandipan Das } 56944dea178SSandipan Das }, 57044dea178SSandipan Das { 57144dea178SSandipan Das .descr = "RA = INT_MIN, RB = INT_MIN", 572*1d33dd84SBalamuruhan S .instr = ppc_inst(PPC_RAW_ADD_DOT(20, 21, 22)), 57344dea178SSandipan Das .regs = { 57444dea178SSandipan Das .gpr[21] = INT_MIN, 57544dea178SSandipan Das .gpr[22] = INT_MIN, 57644dea178SSandipan Das } 57744dea178SSandipan Das }, 57844dea178SSandipan Das { 57944dea178SSandipan Das .descr = "RA = INT_MIN, RB = INT_MAX", 580*1d33dd84SBalamuruhan S .instr = ppc_inst(PPC_RAW_ADD_DOT(20, 21, 22)), 58144dea178SSandipan Das .regs = { 58244dea178SSandipan Das .gpr[21] = INT_MIN, 58344dea178SSandipan Das .gpr[22] = INT_MAX, 58444dea178SSandipan Das } 58544dea178SSandipan Das }, 58644dea178SSandipan Das { 58744dea178SSandipan Das .descr = "RA = INT_MAX, RB = INT_MAX", 588*1d33dd84SBalamuruhan S .instr = ppc_inst(PPC_RAW_ADD_DOT(20, 21, 22)), 58944dea178SSandipan Das .regs = { 59044dea178SSandipan Das .gpr[21] = INT_MAX, 59144dea178SSandipan Das .gpr[22] = INT_MAX, 59244dea178SSandipan Das } 59344dea178SSandipan Das }, 59444dea178SSandipan Das { 59544dea178SSandipan Das .descr = "RA = UINT_MAX, RB = UINT_MAX", 596*1d33dd84SBalamuruhan S .instr = ppc_inst(PPC_RAW_ADD_DOT(20, 21, 22)), 59744dea178SSandipan Das .regs = { 59844dea178SSandipan Das .gpr[21] = UINT_MAX, 59944dea178SSandipan Das .gpr[22] = UINT_MAX, 60044dea178SSandipan Das } 60144dea178SSandipan Das }, 60244dea178SSandipan Das { 60344dea178SSandipan Das .descr = "RA = UINT_MAX, RB = 0x1", 604*1d33dd84SBalamuruhan S .instr = ppc_inst(PPC_RAW_ADD_DOT(20, 21, 22)), 60544dea178SSandipan Das .regs = { 60644dea178SSandipan Das .gpr[21] = UINT_MAX, 60744dea178SSandipan Das .gpr[22] = 0x1, 60844dea178SSandipan Das } 60944dea178SSandipan Das } 61044dea178SSandipan Das } 61178a8da06SSandipan Das }, 61278a8da06SSandipan Das { 61378a8da06SSandipan Das .mnemonic = "addc", 61478a8da06SSandipan Das .subtests = { 61578a8da06SSandipan Das { 61678a8da06SSandipan Das .descr = "RA = LONG_MIN, RB = LONG_MIN", 617*1d33dd84SBalamuruhan S .instr = ppc_inst(PPC_RAW_ADDC(20, 21, 22)), 61878a8da06SSandipan Das .regs = { 61978a8da06SSandipan Das .gpr[21] = LONG_MIN, 62078a8da06SSandipan Das .gpr[22] = LONG_MIN, 62178a8da06SSandipan Das } 62278a8da06SSandipan Das }, 62378a8da06SSandipan Das { 62478a8da06SSandipan Das .descr = "RA = LONG_MIN, RB = LONG_MAX", 625*1d33dd84SBalamuruhan S .instr = ppc_inst(PPC_RAW_ADDC(20, 21, 22)), 62678a8da06SSandipan Das .regs = { 62778a8da06SSandipan Das .gpr[21] = LONG_MIN, 62878a8da06SSandipan Das .gpr[22] = LONG_MAX, 62978a8da06SSandipan Das } 63078a8da06SSandipan Das }, 63178a8da06SSandipan Das { 63278a8da06SSandipan Das .descr = "RA = LONG_MAX, RB = LONG_MAX", 633*1d33dd84SBalamuruhan S .instr = ppc_inst(PPC_RAW_ADDC(20, 21, 22)), 63478a8da06SSandipan Das .regs = { 63578a8da06SSandipan Das .gpr[21] = LONG_MAX, 63678a8da06SSandipan Das .gpr[22] = LONG_MAX, 63778a8da06SSandipan Das } 63878a8da06SSandipan Das }, 63978a8da06SSandipan Das { 64078a8da06SSandipan Das .descr = "RA = ULONG_MAX, RB = ULONG_MAX", 641*1d33dd84SBalamuruhan S .instr = ppc_inst(PPC_RAW_ADDC(20, 21, 22)), 64278a8da06SSandipan Das .regs = { 64378a8da06SSandipan Das .gpr[21] = ULONG_MAX, 64478a8da06SSandipan Das .gpr[22] = ULONG_MAX, 64578a8da06SSandipan Das } 64678a8da06SSandipan Das }, 64778a8da06SSandipan Das { 64878a8da06SSandipan Das .descr = "RA = ULONG_MAX, RB = 0x1", 649*1d33dd84SBalamuruhan S .instr = ppc_inst(PPC_RAW_ADDC(20, 21, 22)), 65078a8da06SSandipan Das .regs = { 65178a8da06SSandipan Das .gpr[21] = ULONG_MAX, 65278a8da06SSandipan Das .gpr[22] = 0x1, 65378a8da06SSandipan Das } 65478a8da06SSandipan Das }, 65578a8da06SSandipan Das { 65678a8da06SSandipan Das .descr = "RA = INT_MIN, RB = INT_MIN", 657*1d33dd84SBalamuruhan S .instr = ppc_inst(PPC_RAW_ADDC(20, 21, 22)), 65878a8da06SSandipan Das .regs = { 65978a8da06SSandipan Das .gpr[21] = INT_MIN, 66078a8da06SSandipan Das .gpr[22] = INT_MIN, 66178a8da06SSandipan Das } 66278a8da06SSandipan Das }, 66378a8da06SSandipan Das { 66478a8da06SSandipan Das .descr = "RA = INT_MIN, RB = INT_MAX", 665*1d33dd84SBalamuruhan S .instr = ppc_inst(PPC_RAW_ADDC(20, 21, 22)), 66678a8da06SSandipan Das .regs = { 66778a8da06SSandipan Das .gpr[21] = INT_MIN, 66878a8da06SSandipan Das .gpr[22] = INT_MAX, 66978a8da06SSandipan Das } 67078a8da06SSandipan Das }, 67178a8da06SSandipan Das { 67278a8da06SSandipan Das .descr = "RA = INT_MAX, RB = INT_MAX", 673*1d33dd84SBalamuruhan S .instr = ppc_inst(PPC_RAW_ADDC(20, 21, 22)), 67478a8da06SSandipan Das .regs = { 67578a8da06SSandipan Das .gpr[21] = INT_MAX, 67678a8da06SSandipan Das .gpr[22] = INT_MAX, 67778a8da06SSandipan Das } 67878a8da06SSandipan Das }, 67978a8da06SSandipan Das { 68078a8da06SSandipan Das .descr = "RA = UINT_MAX, RB = UINT_MAX", 681*1d33dd84SBalamuruhan S .instr = ppc_inst(PPC_RAW_ADDC(20, 21, 22)), 68278a8da06SSandipan Das .regs = { 68378a8da06SSandipan Das .gpr[21] = UINT_MAX, 68478a8da06SSandipan Das .gpr[22] = UINT_MAX, 68578a8da06SSandipan Das } 68678a8da06SSandipan Das }, 68778a8da06SSandipan Das { 68878a8da06SSandipan Das .descr = "RA = UINT_MAX, RB = 0x1", 689*1d33dd84SBalamuruhan S .instr = ppc_inst(PPC_RAW_ADDC(20, 21, 22)), 69078a8da06SSandipan Das .regs = { 69178a8da06SSandipan Das .gpr[21] = UINT_MAX, 69278a8da06SSandipan Das .gpr[22] = 0x1, 69378a8da06SSandipan Das } 69478a8da06SSandipan Das }, 69578a8da06SSandipan Das { 69678a8da06SSandipan Das .descr = "RA = LONG_MIN | INT_MIN, RB = LONG_MIN | INT_MIN", 697*1d33dd84SBalamuruhan S .instr = ppc_inst(PPC_RAW_ADDC(20, 21, 22)), 69878a8da06SSandipan Das .regs = { 69978a8da06SSandipan Das .gpr[21] = LONG_MIN | (uint)INT_MIN, 70078a8da06SSandipan Das .gpr[22] = LONG_MIN | (uint)INT_MIN, 70178a8da06SSandipan Das } 70278a8da06SSandipan Das } 70378a8da06SSandipan Das } 70478a8da06SSandipan Das }, 70578a8da06SSandipan Das { 70678a8da06SSandipan Das .mnemonic = "addc.", 70778a8da06SSandipan Das .subtests = { 70878a8da06SSandipan Das { 70978a8da06SSandipan Das .descr = "RA = LONG_MIN, RB = LONG_MIN", 71078a8da06SSandipan Das .flags = IGNORE_CCR, 711*1d33dd84SBalamuruhan S .instr = ppc_inst(PPC_RAW_ADDC_DOT(20, 21, 22)), 71278a8da06SSandipan Das .regs = { 71378a8da06SSandipan Das .gpr[21] = LONG_MIN, 71478a8da06SSandipan Das .gpr[22] = LONG_MIN, 71578a8da06SSandipan Das } 71678a8da06SSandipan Das }, 71778a8da06SSandipan Das { 71878a8da06SSandipan Das .descr = "RA = LONG_MIN, RB = LONG_MAX", 719*1d33dd84SBalamuruhan S .instr = ppc_inst(PPC_RAW_ADDC_DOT(20, 21, 22)), 72078a8da06SSandipan Das .regs = { 72178a8da06SSandipan Das .gpr[21] = LONG_MIN, 72278a8da06SSandipan Das .gpr[22] = LONG_MAX, 72378a8da06SSandipan Das } 72478a8da06SSandipan Das }, 72578a8da06SSandipan Das { 72678a8da06SSandipan Das .descr = "RA = LONG_MAX, RB = LONG_MAX", 72778a8da06SSandipan Das .flags = IGNORE_CCR, 728*1d33dd84SBalamuruhan S .instr = ppc_inst(PPC_RAW_ADDC_DOT(20, 21, 22)), 72978a8da06SSandipan Das .regs = { 73078a8da06SSandipan Das .gpr[21] = LONG_MAX, 73178a8da06SSandipan Das .gpr[22] = LONG_MAX, 73278a8da06SSandipan Das } 73378a8da06SSandipan Das }, 73478a8da06SSandipan Das { 73578a8da06SSandipan Das .descr = "RA = ULONG_MAX, RB = ULONG_MAX", 736*1d33dd84SBalamuruhan S .instr = ppc_inst(PPC_RAW_ADDC_DOT(20, 21, 22)), 73778a8da06SSandipan Das .regs = { 73878a8da06SSandipan Das .gpr[21] = ULONG_MAX, 73978a8da06SSandipan Das .gpr[22] = ULONG_MAX, 74078a8da06SSandipan Das } 74178a8da06SSandipan Das }, 74278a8da06SSandipan Das { 74378a8da06SSandipan Das .descr = "RA = ULONG_MAX, RB = 0x1", 744*1d33dd84SBalamuruhan S .instr = ppc_inst(PPC_RAW_ADDC_DOT(20, 21, 22)), 74578a8da06SSandipan Das .regs = { 74678a8da06SSandipan Das .gpr[21] = ULONG_MAX, 74778a8da06SSandipan Das .gpr[22] = 0x1, 74878a8da06SSandipan Das } 74978a8da06SSandipan Das }, 75078a8da06SSandipan Das { 75178a8da06SSandipan Das .descr = "RA = INT_MIN, RB = INT_MIN", 752*1d33dd84SBalamuruhan S .instr = ppc_inst(PPC_RAW_ADDC_DOT(20, 21, 22)), 75378a8da06SSandipan Das .regs = { 75478a8da06SSandipan Das .gpr[21] = INT_MIN, 75578a8da06SSandipan Das .gpr[22] = INT_MIN, 75678a8da06SSandipan Das } 75778a8da06SSandipan Das }, 75878a8da06SSandipan Das { 75978a8da06SSandipan Das .descr = "RA = INT_MIN, RB = INT_MAX", 760*1d33dd84SBalamuruhan S .instr = ppc_inst(PPC_RAW_ADDC_DOT(20, 21, 22)), 76178a8da06SSandipan Das .regs = { 76278a8da06SSandipan Das .gpr[21] = INT_MIN, 76378a8da06SSandipan Das .gpr[22] = INT_MAX, 76478a8da06SSandipan Das } 76578a8da06SSandipan Das }, 76678a8da06SSandipan Das { 76778a8da06SSandipan Das .descr = "RA = INT_MAX, RB = INT_MAX", 768*1d33dd84SBalamuruhan S .instr = ppc_inst(PPC_RAW_ADDC_DOT(20, 21, 22)), 76978a8da06SSandipan Das .regs = { 77078a8da06SSandipan Das .gpr[21] = INT_MAX, 77178a8da06SSandipan Das .gpr[22] = INT_MAX, 77278a8da06SSandipan Das } 77378a8da06SSandipan Das }, 77478a8da06SSandipan Das { 77578a8da06SSandipan Das .descr = "RA = UINT_MAX, RB = UINT_MAX", 776*1d33dd84SBalamuruhan S .instr = ppc_inst(PPC_RAW_ADDC_DOT(20, 21, 22)), 77778a8da06SSandipan Das .regs = { 77878a8da06SSandipan Das .gpr[21] = UINT_MAX, 77978a8da06SSandipan Das .gpr[22] = UINT_MAX, 78078a8da06SSandipan Das } 78178a8da06SSandipan Das }, 78278a8da06SSandipan Das { 78378a8da06SSandipan Das .descr = "RA = UINT_MAX, RB = 0x1", 784*1d33dd84SBalamuruhan S .instr = ppc_inst(PPC_RAW_ADDC_DOT(20, 21, 22)), 78578a8da06SSandipan Das .regs = { 78678a8da06SSandipan Das .gpr[21] = UINT_MAX, 78778a8da06SSandipan Das .gpr[22] = 0x1, 78878a8da06SSandipan Das } 78978a8da06SSandipan Das }, 79078a8da06SSandipan Das { 79178a8da06SSandipan Das .descr = "RA = LONG_MIN | INT_MIN, RB = LONG_MIN | INT_MIN", 792*1d33dd84SBalamuruhan S .instr = ppc_inst(PPC_RAW_ADDC_DOT(20, 21, 22)), 79378a8da06SSandipan Das .regs = { 79478a8da06SSandipan Das .gpr[21] = LONG_MIN | (uint)INT_MIN, 79578a8da06SSandipan Das .gpr[22] = LONG_MIN | (uint)INT_MIN, 79678a8da06SSandipan Das } 79778a8da06SSandipan Das } 79878a8da06SSandipan Das } 79984022ac1SSandipan Das } 80084022ac1SSandipan Das }; 80184022ac1SSandipan Das 80284022ac1SSandipan Das static int __init emulate_compute_instr(struct pt_regs *regs, 80394afd069SJordan Niethe struct ppc_inst instr) 80484022ac1SSandipan Das { 80584022ac1SSandipan Das struct instruction_op op; 80684022ac1SSandipan Das 807777e26f0SJordan Niethe if (!regs || !ppc_inst_val(instr)) 80884022ac1SSandipan Das return -EINVAL; 80984022ac1SSandipan Das 81084022ac1SSandipan Das if (analyse_instr(&op, regs, instr) != 1 || 81184022ac1SSandipan Das GETTYPE(op.type) != COMPUTE) { 812777e26f0SJordan Niethe pr_info("emulation failed, instruction = 0x%08x\n", ppc_inst_val(instr)); 81384022ac1SSandipan Das return -EFAULT; 81484022ac1SSandipan Das } 81584022ac1SSandipan Das 81684022ac1SSandipan Das emulate_update_regs(regs, &op); 81784022ac1SSandipan Das return 0; 81884022ac1SSandipan Das } 81984022ac1SSandipan Das 82084022ac1SSandipan Das static int __init execute_compute_instr(struct pt_regs *regs, 82194afd069SJordan Niethe struct ppc_inst instr) 82284022ac1SSandipan Das { 82384022ac1SSandipan Das extern int exec_instr(struct pt_regs *regs); 82484022ac1SSandipan Das extern s32 patch__exec_instr; 82584022ac1SSandipan Das 826777e26f0SJordan Niethe if (!regs || !ppc_inst_val(instr)) 82784022ac1SSandipan Das return -EINVAL; 82884022ac1SSandipan Das 82984022ac1SSandipan Das /* Patch the NOP with the actual instruction */ 83084022ac1SSandipan Das patch_instruction_site(&patch__exec_instr, instr); 83184022ac1SSandipan Das if (exec_instr(regs)) { 832777e26f0SJordan Niethe pr_info("execution failed, instruction = 0x%08x\n", ppc_inst_val(instr)); 83384022ac1SSandipan Das return -EFAULT; 83484022ac1SSandipan Das } 83584022ac1SSandipan Das 83684022ac1SSandipan Das return 0; 83784022ac1SSandipan Das } 83884022ac1SSandipan Das 83984022ac1SSandipan Das #define gpr_mismatch(gprn, exp, got) \ 84084022ac1SSandipan Das pr_info("GPR%u mismatch, exp = 0x%016lx, got = 0x%016lx\n", \ 84184022ac1SSandipan Das gprn, exp, got) 84284022ac1SSandipan Das 84384022ac1SSandipan Das #define reg_mismatch(name, exp, got) \ 84484022ac1SSandipan Das pr_info("%s mismatch, exp = 0x%016lx, got = 0x%016lx\n", \ 84584022ac1SSandipan Das name, exp, got) 84684022ac1SSandipan Das 84784022ac1SSandipan Das static void __init run_tests_compute(void) 84884022ac1SSandipan Das { 84984022ac1SSandipan Das unsigned long flags; 85084022ac1SSandipan Das struct compute_test *test; 85184022ac1SSandipan Das struct pt_regs *regs, exp, got; 85294afd069SJordan Niethe unsigned int i, j, k; 85394afd069SJordan Niethe struct ppc_inst instr; 85484022ac1SSandipan Das bool ignore_gpr, ignore_xer, ignore_ccr, passed; 85584022ac1SSandipan Das 85684022ac1SSandipan Das for (i = 0; i < ARRAY_SIZE(compute_tests); i++) { 85784022ac1SSandipan Das test = &compute_tests[i]; 85884022ac1SSandipan Das 85984022ac1SSandipan Das for (j = 0; j < MAX_SUBTESTS && test->subtests[j].descr; j++) { 86084022ac1SSandipan Das instr = test->subtests[j].instr; 86184022ac1SSandipan Das flags = test->subtests[j].flags; 86284022ac1SSandipan Das regs = &test->subtests[j].regs; 86384022ac1SSandipan Das ignore_xer = flags & IGNORE_XER; 86484022ac1SSandipan Das ignore_ccr = flags & IGNORE_CCR; 86584022ac1SSandipan Das passed = true; 86684022ac1SSandipan Das 86784022ac1SSandipan Das memcpy(&exp, regs, sizeof(struct pt_regs)); 86884022ac1SSandipan Das memcpy(&got, regs, sizeof(struct pt_regs)); 86984022ac1SSandipan Das 87084022ac1SSandipan Das /* 87184022ac1SSandipan Das * Set a compatible MSR value explicitly to ensure 87284022ac1SSandipan Das * that XER and CR bits are updated appropriately 87384022ac1SSandipan Das */ 87484022ac1SSandipan Das exp.msr = MSR_KERNEL; 87584022ac1SSandipan Das got.msr = MSR_KERNEL; 87684022ac1SSandipan Das 87784022ac1SSandipan Das if (emulate_compute_instr(&got, instr) || 87884022ac1SSandipan Das execute_compute_instr(&exp, instr)) { 87984022ac1SSandipan Das passed = false; 88084022ac1SSandipan Das goto print; 88184022ac1SSandipan Das } 88284022ac1SSandipan Das 88384022ac1SSandipan Das /* Verify GPR values */ 88484022ac1SSandipan Das for (k = 0; k < 32; k++) { 88584022ac1SSandipan Das ignore_gpr = flags & IGNORE_GPR(k); 88684022ac1SSandipan Das if (!ignore_gpr && exp.gpr[k] != got.gpr[k]) { 88784022ac1SSandipan Das passed = false; 88884022ac1SSandipan Das gpr_mismatch(k, exp.gpr[k], got.gpr[k]); 88984022ac1SSandipan Das } 89084022ac1SSandipan Das } 89184022ac1SSandipan Das 89284022ac1SSandipan Das /* Verify LR value */ 89384022ac1SSandipan Das if (exp.link != got.link) { 89484022ac1SSandipan Das passed = false; 89584022ac1SSandipan Das reg_mismatch("LR", exp.link, got.link); 89684022ac1SSandipan Das } 89784022ac1SSandipan Das 89884022ac1SSandipan Das /* Verify XER value */ 89984022ac1SSandipan Das if (!ignore_xer && exp.xer != got.xer) { 90084022ac1SSandipan Das passed = false; 90184022ac1SSandipan Das reg_mismatch("XER", exp.xer, got.xer); 90284022ac1SSandipan Das } 90384022ac1SSandipan Das 90484022ac1SSandipan Das /* Verify CR value */ 90584022ac1SSandipan Das if (!ignore_ccr && exp.ccr != got.ccr) { 90684022ac1SSandipan Das passed = false; 90784022ac1SSandipan Das reg_mismatch("CR", exp.ccr, got.ccr); 90884022ac1SSandipan Das } 90984022ac1SSandipan Das 91084022ac1SSandipan Das print: 91184022ac1SSandipan Das show_result_with_descr(test->mnemonic, 91284022ac1SSandipan Das test->subtests[j].descr, 91384022ac1SSandipan Das passed ? "PASS" : "FAIL"); 91484022ac1SSandipan Das } 91584022ac1SSandipan Das } 91684022ac1SSandipan Das } 91784022ac1SSandipan Das 91884022ac1SSandipan Das static int __init test_emulate_step(void) 91984022ac1SSandipan Das { 92084022ac1SSandipan Das printk(KERN_INFO "Running instruction emulation self-tests ...\n"); 92184022ac1SSandipan Das run_tests_load_store(); 92284022ac1SSandipan Das run_tests_compute(); 9234ceae137SRavi Bangoria 9244ceae137SRavi Bangoria return 0; 9254ceae137SRavi Bangoria } 9264ceae137SRavi Bangoria late_initcall(test_emulate_step); 927