xref: /openbmc/linux/arch/powerpc/lib/test_emulate_step.c (revision 44dea1784b2fdea3aec20c14306aebbeb4294f64)
14ceae137SRavi Bangoria /*
284022ac1SSandipan Das  * Simple sanity tests for instruction emulation infrastructure.
34ceae137SRavi Bangoria  *
44ceae137SRavi Bangoria  * Copyright IBM Corp. 2016
54ceae137SRavi Bangoria  *
64ceae137SRavi Bangoria  * This program is free software;  you can redistribute it and/or modify
74ceae137SRavi Bangoria  * it under the terms of the GNU General Public License as published by
84ceae137SRavi Bangoria  * the Free Software Foundation; either version 2 of the License, or
94ceae137SRavi Bangoria  * (at your option) any later version.
104ceae137SRavi Bangoria  */
114ceae137SRavi Bangoria 
124ceae137SRavi Bangoria #define pr_fmt(fmt) "emulate_step_test: " fmt
134ceae137SRavi Bangoria 
144ceae137SRavi Bangoria #include <linux/ptrace.h>
154ceae137SRavi Bangoria #include <asm/sstep.h>
164ceae137SRavi Bangoria #include <asm/ppc-opcode.h>
1784022ac1SSandipan Das #include <asm/code-patching.h>
184ceae137SRavi Bangoria 
194ceae137SRavi Bangoria #define IMM_L(i)		((uintptr_t)(i) & 0xffff)
204ceae137SRavi Bangoria 
214ceae137SRavi Bangoria /*
224ceae137SRavi Bangoria  * Defined with TEST_ prefix so it does not conflict with other
234ceae137SRavi Bangoria  * definitions.
244ceae137SRavi Bangoria  */
254ceae137SRavi Bangoria #define TEST_LD(r, base, i)	(PPC_INST_LD | ___PPC_RT(r) |		\
264ceae137SRavi Bangoria 					___PPC_RA(base) | IMM_L(i))
274ceae137SRavi Bangoria #define TEST_LWZ(r, base, i)	(PPC_INST_LWZ | ___PPC_RT(r) |		\
284ceae137SRavi Bangoria 					___PPC_RA(base) | IMM_L(i))
294ceae137SRavi Bangoria #define TEST_LWZX(t, a, b)	(PPC_INST_LWZX | ___PPC_RT(t) |		\
304ceae137SRavi Bangoria 					___PPC_RA(a) | ___PPC_RB(b))
314ceae137SRavi Bangoria #define TEST_STD(r, base, i)	(PPC_INST_STD | ___PPC_RS(r) |		\
324ceae137SRavi Bangoria 					___PPC_RA(base) | ((i) & 0xfffc))
334ceae137SRavi Bangoria #define TEST_LDARX(t, a, b, eh)	(PPC_INST_LDARX | ___PPC_RT(t) |	\
344ceae137SRavi Bangoria 					___PPC_RA(a) | ___PPC_RB(b) |	\
354ceae137SRavi Bangoria 					__PPC_EH(eh))
364ceae137SRavi Bangoria #define TEST_STDCX(s, a, b)	(PPC_INST_STDCX | ___PPC_RS(s) |	\
374ceae137SRavi Bangoria 					___PPC_RA(a) | ___PPC_RB(b))
384ceae137SRavi Bangoria #define TEST_LFSX(t, a, b)	(PPC_INST_LFSX | ___PPC_RT(t) |		\
394ceae137SRavi Bangoria 					___PPC_RA(a) | ___PPC_RB(b))
404ceae137SRavi Bangoria #define TEST_STFSX(s, a, b)	(PPC_INST_STFSX | ___PPC_RS(s) |	\
414ceae137SRavi Bangoria 					___PPC_RA(a) | ___PPC_RB(b))
424ceae137SRavi Bangoria #define TEST_LFDX(t, a, b)	(PPC_INST_LFDX | ___PPC_RT(t) |		\
434ceae137SRavi Bangoria 					___PPC_RA(a) | ___PPC_RB(b))
444ceae137SRavi Bangoria #define TEST_STFDX(s, a, b)	(PPC_INST_STFDX | ___PPC_RS(s) |	\
454ceae137SRavi Bangoria 					___PPC_RA(a) | ___PPC_RB(b))
464ceae137SRavi Bangoria #define TEST_LVX(t, a, b)	(PPC_INST_LVX | ___PPC_RT(t) |		\
474ceae137SRavi Bangoria 					___PPC_RA(a) | ___PPC_RB(b))
484ceae137SRavi Bangoria #define TEST_STVX(s, a, b)	(PPC_INST_STVX | ___PPC_RS(s) |		\
494ceae137SRavi Bangoria 					___PPC_RA(a) | ___PPC_RB(b))
504ceae137SRavi Bangoria #define TEST_LXVD2X(s, a, b)	(PPC_INST_LXVD2X | VSX_XX1((s), R##a, R##b))
514ceae137SRavi Bangoria #define TEST_STXVD2X(s, a, b)	(PPC_INST_STXVD2X | VSX_XX1((s), R##a, R##b))
52*44dea178SSandipan Das #define TEST_ADD(t, a, b)	(PPC_INST_ADD | ___PPC_RT(t) |		\
53*44dea178SSandipan Das 					___PPC_RA(a) | ___PPC_RB(b))
54*44dea178SSandipan Das #define TEST_ADD_DOT(t, a, b)	(PPC_INST_ADD | ___PPC_RT(t) |		\
55*44dea178SSandipan Das 					___PPC_RA(a) | ___PPC_RB(b) | 0x1)
564ceae137SRavi Bangoria 
5784022ac1SSandipan Das #define MAX_SUBTESTS	16
5884022ac1SSandipan Das 
5984022ac1SSandipan Das #define IGNORE_GPR(n)	(0x1UL << (n))
6084022ac1SSandipan Das #define IGNORE_XER	(0x1UL << 32)
6184022ac1SSandipan Das #define IGNORE_CCR	(0x1UL << 33)
624ceae137SRavi Bangoria 
634ceae137SRavi Bangoria static void __init init_pt_regs(struct pt_regs *regs)
644ceae137SRavi Bangoria {
654ceae137SRavi Bangoria 	static unsigned long msr;
664ceae137SRavi Bangoria 	static bool msr_cached;
674ceae137SRavi Bangoria 
684ceae137SRavi Bangoria 	memset(regs, 0, sizeof(struct pt_regs));
694ceae137SRavi Bangoria 
704ceae137SRavi Bangoria 	if (likely(msr_cached)) {
714ceae137SRavi Bangoria 		regs->msr = msr;
724ceae137SRavi Bangoria 		return;
734ceae137SRavi Bangoria 	}
744ceae137SRavi Bangoria 
754ceae137SRavi Bangoria 	asm volatile("mfmsr %0" : "=r"(regs->msr));
764ceae137SRavi Bangoria 
774ceae137SRavi Bangoria 	regs->msr |= MSR_FP;
784ceae137SRavi Bangoria 	regs->msr |= MSR_VEC;
794ceae137SRavi Bangoria 	regs->msr |= MSR_VSX;
804ceae137SRavi Bangoria 
814ceae137SRavi Bangoria 	msr = regs->msr;
824ceae137SRavi Bangoria 	msr_cached = true;
834ceae137SRavi Bangoria }
844ceae137SRavi Bangoria 
8584022ac1SSandipan Das static void __init show_result(char *mnemonic, char *result)
864ceae137SRavi Bangoria {
8784022ac1SSandipan Das 	pr_info("%-14s : %s\n", mnemonic, result);
8884022ac1SSandipan Das }
8984022ac1SSandipan Das 
9084022ac1SSandipan Das static void __init show_result_with_descr(char *mnemonic, char *descr,
9184022ac1SSandipan Das 					  char *result)
9284022ac1SSandipan Das {
9384022ac1SSandipan Das 	pr_info("%-14s : %-50s %s\n", mnemonic, descr, result);
944ceae137SRavi Bangoria }
954ceae137SRavi Bangoria 
964ceae137SRavi Bangoria static void __init test_ld(void)
974ceae137SRavi Bangoria {
984ceae137SRavi Bangoria 	struct pt_regs regs;
994ceae137SRavi Bangoria 	unsigned long a = 0x23;
1004ceae137SRavi Bangoria 	int stepped = -1;
1014ceae137SRavi Bangoria 
1024ceae137SRavi Bangoria 	init_pt_regs(&regs);
1034ceae137SRavi Bangoria 	regs.gpr[3] = (unsigned long) &a;
1044ceae137SRavi Bangoria 
1054ceae137SRavi Bangoria 	/* ld r5, 0(r3) */
1064ceae137SRavi Bangoria 	stepped = emulate_step(&regs, TEST_LD(5, 3, 0));
1074ceae137SRavi Bangoria 
1084ceae137SRavi Bangoria 	if (stepped == 1 && regs.gpr[5] == a)
1094ceae137SRavi Bangoria 		show_result("ld", "PASS");
1104ceae137SRavi Bangoria 	else
1114ceae137SRavi Bangoria 		show_result("ld", "FAIL");
1124ceae137SRavi Bangoria }
1134ceae137SRavi Bangoria 
1144ceae137SRavi Bangoria static void __init test_lwz(void)
1154ceae137SRavi Bangoria {
1164ceae137SRavi Bangoria 	struct pt_regs regs;
1174ceae137SRavi Bangoria 	unsigned int a = 0x4545;
1184ceae137SRavi Bangoria 	int stepped = -1;
1194ceae137SRavi Bangoria 
1204ceae137SRavi Bangoria 	init_pt_regs(&regs);
1214ceae137SRavi Bangoria 	regs.gpr[3] = (unsigned long) &a;
1224ceae137SRavi Bangoria 
1234ceae137SRavi Bangoria 	/* lwz r5, 0(r3) */
1244ceae137SRavi Bangoria 	stepped = emulate_step(&regs, TEST_LWZ(5, 3, 0));
1254ceae137SRavi Bangoria 
1264ceae137SRavi Bangoria 	if (stepped == 1 && regs.gpr[5] == a)
1274ceae137SRavi Bangoria 		show_result("lwz", "PASS");
1284ceae137SRavi Bangoria 	else
1294ceae137SRavi Bangoria 		show_result("lwz", "FAIL");
1304ceae137SRavi Bangoria }
1314ceae137SRavi Bangoria 
1324ceae137SRavi Bangoria static void __init test_lwzx(void)
1334ceae137SRavi Bangoria {
1344ceae137SRavi Bangoria 	struct pt_regs regs;
1354ceae137SRavi Bangoria 	unsigned int a[3] = {0x0, 0x0, 0x1234};
1364ceae137SRavi Bangoria 	int stepped = -1;
1374ceae137SRavi Bangoria 
1384ceae137SRavi Bangoria 	init_pt_regs(&regs);
1394ceae137SRavi Bangoria 	regs.gpr[3] = (unsigned long) a;
1404ceae137SRavi Bangoria 	regs.gpr[4] = 8;
1414ceae137SRavi Bangoria 	regs.gpr[5] = 0x8765;
1424ceae137SRavi Bangoria 
1434ceae137SRavi Bangoria 	/* lwzx r5, r3, r4 */
1444ceae137SRavi Bangoria 	stepped = emulate_step(&regs, TEST_LWZX(5, 3, 4));
1454ceae137SRavi Bangoria 	if (stepped == 1 && regs.gpr[5] == a[2])
1464ceae137SRavi Bangoria 		show_result("lwzx", "PASS");
1474ceae137SRavi Bangoria 	else
1484ceae137SRavi Bangoria 		show_result("lwzx", "FAIL");
1494ceae137SRavi Bangoria }
1504ceae137SRavi Bangoria 
1514ceae137SRavi Bangoria static void __init test_std(void)
1524ceae137SRavi Bangoria {
1534ceae137SRavi Bangoria 	struct pt_regs regs;
1544ceae137SRavi Bangoria 	unsigned long a = 0x1234;
1554ceae137SRavi Bangoria 	int stepped = -1;
1564ceae137SRavi Bangoria 
1574ceae137SRavi Bangoria 	init_pt_regs(&regs);
1584ceae137SRavi Bangoria 	regs.gpr[3] = (unsigned long) &a;
1594ceae137SRavi Bangoria 	regs.gpr[5] = 0x5678;
1604ceae137SRavi Bangoria 
1614ceae137SRavi Bangoria 	/* std r5, 0(r3) */
1624ceae137SRavi Bangoria 	stepped = emulate_step(&regs, TEST_STD(5, 3, 0));
1634ceae137SRavi Bangoria 	if (stepped == 1 || regs.gpr[5] == a)
1644ceae137SRavi Bangoria 		show_result("std", "PASS");
1654ceae137SRavi Bangoria 	else
1664ceae137SRavi Bangoria 		show_result("std", "FAIL");
1674ceae137SRavi Bangoria }
1684ceae137SRavi Bangoria 
1694ceae137SRavi Bangoria static void __init test_ldarx_stdcx(void)
1704ceae137SRavi Bangoria {
1714ceae137SRavi Bangoria 	struct pt_regs regs;
1724ceae137SRavi Bangoria 	unsigned long a = 0x1234;
1734ceae137SRavi Bangoria 	int stepped = -1;
1744ceae137SRavi Bangoria 	unsigned long cr0_eq = 0x1 << 29; /* eq bit of CR0 */
1754ceae137SRavi Bangoria 
1764ceae137SRavi Bangoria 	init_pt_regs(&regs);
1774ceae137SRavi Bangoria 	asm volatile("mfcr %0" : "=r"(regs.ccr));
1784ceae137SRavi Bangoria 
1794ceae137SRavi Bangoria 
1804ceae137SRavi Bangoria 	/*** ldarx ***/
1814ceae137SRavi Bangoria 
1824ceae137SRavi Bangoria 	regs.gpr[3] = (unsigned long) &a;
1834ceae137SRavi Bangoria 	regs.gpr[4] = 0;
1844ceae137SRavi Bangoria 	regs.gpr[5] = 0x5678;
1854ceae137SRavi Bangoria 
1864ceae137SRavi Bangoria 	/* ldarx r5, r3, r4, 0 */
1874ceae137SRavi Bangoria 	stepped = emulate_step(&regs, TEST_LDARX(5, 3, 4, 0));
1884ceae137SRavi Bangoria 
1894ceae137SRavi Bangoria 	/*
1904ceae137SRavi Bangoria 	 * Don't touch 'a' here. Touching 'a' can do Load/store
1914ceae137SRavi Bangoria 	 * of 'a' which result in failure of subsequent stdcx.
1924ceae137SRavi Bangoria 	 * Instead, use hardcoded value for comparison.
1934ceae137SRavi Bangoria 	 */
1944ceae137SRavi Bangoria 	if (stepped <= 0 || regs.gpr[5] != 0x1234) {
1954ceae137SRavi Bangoria 		show_result("ldarx / stdcx.", "FAIL (ldarx)");
1964ceae137SRavi Bangoria 		return;
1974ceae137SRavi Bangoria 	}
1984ceae137SRavi Bangoria 
1994ceae137SRavi Bangoria 
2004ceae137SRavi Bangoria 	/*** stdcx. ***/
2014ceae137SRavi Bangoria 
2024ceae137SRavi Bangoria 	regs.gpr[5] = 0x9ABC;
2034ceae137SRavi Bangoria 
2044ceae137SRavi Bangoria 	/* stdcx. r5, r3, r4 */
2054ceae137SRavi Bangoria 	stepped = emulate_step(&regs, TEST_STDCX(5, 3, 4));
2064ceae137SRavi Bangoria 
2074ceae137SRavi Bangoria 	/*
2084ceae137SRavi Bangoria 	 * Two possible scenarios that indicates successful emulation
2094ceae137SRavi Bangoria 	 * of stdcx. :
2104ceae137SRavi Bangoria 	 *  1. Reservation is active and store is performed. In this
2114ceae137SRavi Bangoria 	 *     case cr0.eq bit will be set to 1.
2124ceae137SRavi Bangoria 	 *  2. Reservation is not active and store is not performed.
2134ceae137SRavi Bangoria 	 *     In this case cr0.eq bit will be set to 0.
2144ceae137SRavi Bangoria 	 */
2154ceae137SRavi Bangoria 	if (stepped == 1 && ((regs.gpr[5] == a && (regs.ccr & cr0_eq))
2164ceae137SRavi Bangoria 			|| (regs.gpr[5] != a && !(regs.ccr & cr0_eq))))
2174ceae137SRavi Bangoria 		show_result("ldarx / stdcx.", "PASS");
2184ceae137SRavi Bangoria 	else
2194ceae137SRavi Bangoria 		show_result("ldarx / stdcx.", "FAIL (stdcx.)");
2204ceae137SRavi Bangoria }
2214ceae137SRavi Bangoria 
2224ceae137SRavi Bangoria #ifdef CONFIG_PPC_FPU
2234ceae137SRavi Bangoria static void __init test_lfsx_stfsx(void)
2244ceae137SRavi Bangoria {
2254ceae137SRavi Bangoria 	struct pt_regs regs;
2264ceae137SRavi Bangoria 	union {
2274ceae137SRavi Bangoria 		float a;
2284ceae137SRavi Bangoria 		int b;
2294ceae137SRavi Bangoria 	} c;
2304ceae137SRavi Bangoria 	int cached_b;
2314ceae137SRavi Bangoria 	int stepped = -1;
2324ceae137SRavi Bangoria 
2334ceae137SRavi Bangoria 	init_pt_regs(&regs);
2344ceae137SRavi Bangoria 
2354ceae137SRavi Bangoria 
2364ceae137SRavi Bangoria 	/*** lfsx ***/
2374ceae137SRavi Bangoria 
2384ceae137SRavi Bangoria 	c.a = 123.45;
2394ceae137SRavi Bangoria 	cached_b = c.b;
2404ceae137SRavi Bangoria 
2414ceae137SRavi Bangoria 	regs.gpr[3] = (unsigned long) &c.a;
2424ceae137SRavi Bangoria 	regs.gpr[4] = 0;
2434ceae137SRavi Bangoria 
2444ceae137SRavi Bangoria 	/* lfsx frt10, r3, r4 */
2454ceae137SRavi Bangoria 	stepped = emulate_step(&regs, TEST_LFSX(10, 3, 4));
2464ceae137SRavi Bangoria 
2474ceae137SRavi Bangoria 	if (stepped == 1)
2484ceae137SRavi Bangoria 		show_result("lfsx", "PASS");
2494ceae137SRavi Bangoria 	else
2504ceae137SRavi Bangoria 		show_result("lfsx", "FAIL");
2514ceae137SRavi Bangoria 
2524ceae137SRavi Bangoria 
2534ceae137SRavi Bangoria 	/*** stfsx ***/
2544ceae137SRavi Bangoria 
2554ceae137SRavi Bangoria 	c.a = 678.91;
2564ceae137SRavi Bangoria 
2574ceae137SRavi Bangoria 	/* stfsx frs10, r3, r4 */
2584ceae137SRavi Bangoria 	stepped = emulate_step(&regs, TEST_STFSX(10, 3, 4));
2594ceae137SRavi Bangoria 
2604ceae137SRavi Bangoria 	if (stepped == 1 && c.b == cached_b)
2614ceae137SRavi Bangoria 		show_result("stfsx", "PASS");
2624ceae137SRavi Bangoria 	else
2634ceae137SRavi Bangoria 		show_result("stfsx", "FAIL");
2644ceae137SRavi Bangoria }
2654ceae137SRavi Bangoria 
2664ceae137SRavi Bangoria static void __init test_lfdx_stfdx(void)
2674ceae137SRavi Bangoria {
2684ceae137SRavi Bangoria 	struct pt_regs regs;
2694ceae137SRavi Bangoria 	union {
2704ceae137SRavi Bangoria 		double a;
2714ceae137SRavi Bangoria 		long b;
2724ceae137SRavi Bangoria 	} c;
2734ceae137SRavi Bangoria 	long cached_b;
2744ceae137SRavi Bangoria 	int stepped = -1;
2754ceae137SRavi Bangoria 
2764ceae137SRavi Bangoria 	init_pt_regs(&regs);
2774ceae137SRavi Bangoria 
2784ceae137SRavi Bangoria 
2794ceae137SRavi Bangoria 	/*** lfdx ***/
2804ceae137SRavi Bangoria 
2814ceae137SRavi Bangoria 	c.a = 123456.78;
2824ceae137SRavi Bangoria 	cached_b = c.b;
2834ceae137SRavi Bangoria 
2844ceae137SRavi Bangoria 	regs.gpr[3] = (unsigned long) &c.a;
2854ceae137SRavi Bangoria 	regs.gpr[4] = 0;
2864ceae137SRavi Bangoria 
2874ceae137SRavi Bangoria 	/* lfdx frt10, r3, r4 */
2884ceae137SRavi Bangoria 	stepped = emulate_step(&regs, TEST_LFDX(10, 3, 4));
2894ceae137SRavi Bangoria 
2904ceae137SRavi Bangoria 	if (stepped == 1)
2914ceae137SRavi Bangoria 		show_result("lfdx", "PASS");
2924ceae137SRavi Bangoria 	else
2934ceae137SRavi Bangoria 		show_result("lfdx", "FAIL");
2944ceae137SRavi Bangoria 
2954ceae137SRavi Bangoria 
2964ceae137SRavi Bangoria 	/*** stfdx ***/
2974ceae137SRavi Bangoria 
2984ceae137SRavi Bangoria 	c.a = 987654.32;
2994ceae137SRavi Bangoria 
3004ceae137SRavi Bangoria 	/* stfdx frs10, r3, r4 */
3014ceae137SRavi Bangoria 	stepped = emulate_step(&regs, TEST_STFDX(10, 3, 4));
3024ceae137SRavi Bangoria 
3034ceae137SRavi Bangoria 	if (stepped == 1 && c.b == cached_b)
3044ceae137SRavi Bangoria 		show_result("stfdx", "PASS");
3054ceae137SRavi Bangoria 	else
3064ceae137SRavi Bangoria 		show_result("stfdx", "FAIL");
3074ceae137SRavi Bangoria }
3084ceae137SRavi Bangoria #else
3094ceae137SRavi Bangoria static void __init test_lfsx_stfsx(void)
3104ceae137SRavi Bangoria {
3114ceae137SRavi Bangoria 	show_result("lfsx", "SKIP (CONFIG_PPC_FPU is not set)");
3124ceae137SRavi Bangoria 	show_result("stfsx", "SKIP (CONFIG_PPC_FPU is not set)");
3134ceae137SRavi Bangoria }
3144ceae137SRavi Bangoria 
3154ceae137SRavi Bangoria static void __init test_lfdx_stfdx(void)
3164ceae137SRavi Bangoria {
3174ceae137SRavi Bangoria 	show_result("lfdx", "SKIP (CONFIG_PPC_FPU is not set)");
3184ceae137SRavi Bangoria 	show_result("stfdx", "SKIP (CONFIG_PPC_FPU is not set)");
3194ceae137SRavi Bangoria }
3204ceae137SRavi Bangoria #endif /* CONFIG_PPC_FPU */
3214ceae137SRavi Bangoria 
3224ceae137SRavi Bangoria #ifdef CONFIG_ALTIVEC
3234ceae137SRavi Bangoria static void __init test_lvx_stvx(void)
3244ceae137SRavi Bangoria {
3254ceae137SRavi Bangoria 	struct pt_regs regs;
3264ceae137SRavi Bangoria 	union {
3274ceae137SRavi Bangoria 		vector128 a;
3284ceae137SRavi Bangoria 		u32 b[4];
3294ceae137SRavi Bangoria 	} c;
3304ceae137SRavi Bangoria 	u32 cached_b[4];
3314ceae137SRavi Bangoria 	int stepped = -1;
3324ceae137SRavi Bangoria 
3334ceae137SRavi Bangoria 	init_pt_regs(&regs);
3344ceae137SRavi Bangoria 
3354ceae137SRavi Bangoria 
3364ceae137SRavi Bangoria 	/*** lvx ***/
3374ceae137SRavi Bangoria 
3384ceae137SRavi Bangoria 	cached_b[0] = c.b[0] = 923745;
3394ceae137SRavi Bangoria 	cached_b[1] = c.b[1] = 2139478;
3404ceae137SRavi Bangoria 	cached_b[2] = c.b[2] = 9012;
3414ceae137SRavi Bangoria 	cached_b[3] = c.b[3] = 982134;
3424ceae137SRavi Bangoria 
3434ceae137SRavi Bangoria 	regs.gpr[3] = (unsigned long) &c.a;
3444ceae137SRavi Bangoria 	regs.gpr[4] = 0;
3454ceae137SRavi Bangoria 
3464ceae137SRavi Bangoria 	/* lvx vrt10, r3, r4 */
3474ceae137SRavi Bangoria 	stepped = emulate_step(&regs, TEST_LVX(10, 3, 4));
3484ceae137SRavi Bangoria 
3494ceae137SRavi Bangoria 	if (stepped == 1)
3504ceae137SRavi Bangoria 		show_result("lvx", "PASS");
3514ceae137SRavi Bangoria 	else
3524ceae137SRavi Bangoria 		show_result("lvx", "FAIL");
3534ceae137SRavi Bangoria 
3544ceae137SRavi Bangoria 
3554ceae137SRavi Bangoria 	/*** stvx ***/
3564ceae137SRavi Bangoria 
3574ceae137SRavi Bangoria 	c.b[0] = 4987513;
3584ceae137SRavi Bangoria 	c.b[1] = 84313948;
3594ceae137SRavi Bangoria 	c.b[2] = 71;
3604ceae137SRavi Bangoria 	c.b[3] = 498532;
3614ceae137SRavi Bangoria 
3624ceae137SRavi Bangoria 	/* stvx vrs10, r3, r4 */
3634ceae137SRavi Bangoria 	stepped = emulate_step(&regs, TEST_STVX(10, 3, 4));
3644ceae137SRavi Bangoria 
3654ceae137SRavi Bangoria 	if (stepped == 1 && cached_b[0] == c.b[0] && cached_b[1] == c.b[1] &&
3664ceae137SRavi Bangoria 	    cached_b[2] == c.b[2] && cached_b[3] == c.b[3])
3674ceae137SRavi Bangoria 		show_result("stvx", "PASS");
3684ceae137SRavi Bangoria 	else
3694ceae137SRavi Bangoria 		show_result("stvx", "FAIL");
3704ceae137SRavi Bangoria }
3714ceae137SRavi Bangoria #else
3724ceae137SRavi Bangoria static void __init test_lvx_stvx(void)
3734ceae137SRavi Bangoria {
3744ceae137SRavi Bangoria 	show_result("lvx", "SKIP (CONFIG_ALTIVEC is not set)");
3754ceae137SRavi Bangoria 	show_result("stvx", "SKIP (CONFIG_ALTIVEC is not set)");
3764ceae137SRavi Bangoria }
3774ceae137SRavi Bangoria #endif /* CONFIG_ALTIVEC */
3784ceae137SRavi Bangoria 
3794ceae137SRavi Bangoria #ifdef CONFIG_VSX
3804ceae137SRavi Bangoria static void __init test_lxvd2x_stxvd2x(void)
3814ceae137SRavi Bangoria {
3824ceae137SRavi Bangoria 	struct pt_regs regs;
3834ceae137SRavi Bangoria 	union {
3844ceae137SRavi Bangoria 		vector128 a;
3854ceae137SRavi Bangoria 		u32 b[4];
3864ceae137SRavi Bangoria 	} c;
3874ceae137SRavi Bangoria 	u32 cached_b[4];
3884ceae137SRavi Bangoria 	int stepped = -1;
3894ceae137SRavi Bangoria 
3904ceae137SRavi Bangoria 	init_pt_regs(&regs);
3914ceae137SRavi Bangoria 
3924ceae137SRavi Bangoria 
3934ceae137SRavi Bangoria 	/*** lxvd2x ***/
3944ceae137SRavi Bangoria 
3954ceae137SRavi Bangoria 	cached_b[0] = c.b[0] = 18233;
3964ceae137SRavi Bangoria 	cached_b[1] = c.b[1] = 34863571;
3974ceae137SRavi Bangoria 	cached_b[2] = c.b[2] = 834;
3984ceae137SRavi Bangoria 	cached_b[3] = c.b[3] = 6138911;
3994ceae137SRavi Bangoria 
4004ceae137SRavi Bangoria 	regs.gpr[3] = (unsigned long) &c.a;
4014ceae137SRavi Bangoria 	regs.gpr[4] = 0;
4024ceae137SRavi Bangoria 
4034ceae137SRavi Bangoria 	/* lxvd2x vsr39, r3, r4 */
4044ceae137SRavi Bangoria 	stepped = emulate_step(&regs, TEST_LXVD2X(39, 3, 4));
4054ceae137SRavi Bangoria 
4065a61640eSRavi Bangoria 	if (stepped == 1 && cpu_has_feature(CPU_FTR_VSX)) {
4074ceae137SRavi Bangoria 		show_result("lxvd2x", "PASS");
4085a61640eSRavi Bangoria 	} else {
4095a61640eSRavi Bangoria 		if (!cpu_has_feature(CPU_FTR_VSX))
4105a61640eSRavi Bangoria 			show_result("lxvd2x", "PASS (!CPU_FTR_VSX)");
4114ceae137SRavi Bangoria 		else
4124ceae137SRavi Bangoria 			show_result("lxvd2x", "FAIL");
4135a61640eSRavi Bangoria 	}
4144ceae137SRavi Bangoria 
4154ceae137SRavi Bangoria 
4164ceae137SRavi Bangoria 	/*** stxvd2x ***/
4174ceae137SRavi Bangoria 
4184ceae137SRavi Bangoria 	c.b[0] = 21379463;
4194ceae137SRavi Bangoria 	c.b[1] = 87;
4204ceae137SRavi Bangoria 	c.b[2] = 374234;
4214ceae137SRavi Bangoria 	c.b[3] = 4;
4224ceae137SRavi Bangoria 
4234ceae137SRavi Bangoria 	/* stxvd2x vsr39, r3, r4 */
4244ceae137SRavi Bangoria 	stepped = emulate_step(&regs, TEST_STXVD2X(39, 3, 4));
4254ceae137SRavi Bangoria 
4264ceae137SRavi Bangoria 	if (stepped == 1 && cached_b[0] == c.b[0] && cached_b[1] == c.b[1] &&
4275a61640eSRavi Bangoria 	    cached_b[2] == c.b[2] && cached_b[3] == c.b[3] &&
4285a61640eSRavi Bangoria 	    cpu_has_feature(CPU_FTR_VSX)) {
4294ceae137SRavi Bangoria 		show_result("stxvd2x", "PASS");
4305a61640eSRavi Bangoria 	} else {
4315a61640eSRavi Bangoria 		if (!cpu_has_feature(CPU_FTR_VSX))
4325a61640eSRavi Bangoria 			show_result("stxvd2x", "PASS (!CPU_FTR_VSX)");
4334ceae137SRavi Bangoria 		else
4344ceae137SRavi Bangoria 			show_result("stxvd2x", "FAIL");
4354ceae137SRavi Bangoria 	}
4365a61640eSRavi Bangoria }
4374ceae137SRavi Bangoria #else
4384ceae137SRavi Bangoria static void __init test_lxvd2x_stxvd2x(void)
4394ceae137SRavi Bangoria {
4404ceae137SRavi Bangoria 	show_result("lxvd2x", "SKIP (CONFIG_VSX is not set)");
4414ceae137SRavi Bangoria 	show_result("stxvd2x", "SKIP (CONFIG_VSX is not set)");
4424ceae137SRavi Bangoria }
4434ceae137SRavi Bangoria #endif /* CONFIG_VSX */
4444ceae137SRavi Bangoria 
44584022ac1SSandipan Das static void __init run_tests_load_store(void)
4464ceae137SRavi Bangoria {
4474ceae137SRavi Bangoria 	test_ld();
4484ceae137SRavi Bangoria 	test_lwz();
4494ceae137SRavi Bangoria 	test_lwzx();
4504ceae137SRavi Bangoria 	test_std();
4514ceae137SRavi Bangoria 	test_ldarx_stdcx();
4524ceae137SRavi Bangoria 	test_lfsx_stfsx();
4534ceae137SRavi Bangoria 	test_lfdx_stfdx();
4544ceae137SRavi Bangoria 	test_lvx_stvx();
4554ceae137SRavi Bangoria 	test_lxvd2x_stxvd2x();
45684022ac1SSandipan Das }
45784022ac1SSandipan Das 
45884022ac1SSandipan Das struct compute_test {
45984022ac1SSandipan Das 	char *mnemonic;
46084022ac1SSandipan Das 	struct {
46184022ac1SSandipan Das 		char *descr;
46284022ac1SSandipan Das 		unsigned long flags;
46384022ac1SSandipan Das 		unsigned int instr;
46484022ac1SSandipan Das 		struct pt_regs regs;
46584022ac1SSandipan Das 	} subtests[MAX_SUBTESTS + 1];
46684022ac1SSandipan Das };
46784022ac1SSandipan Das 
46884022ac1SSandipan Das static struct compute_test compute_tests[] = {
46984022ac1SSandipan Das 	{
47084022ac1SSandipan Das 		.mnemonic = "nop",
47184022ac1SSandipan Das 		.subtests = {
47284022ac1SSandipan Das 			{
47384022ac1SSandipan Das 				.descr = "R0 = LONG_MAX",
47484022ac1SSandipan Das 				.instr = PPC_INST_NOP,
47584022ac1SSandipan Das 				.regs = {
47684022ac1SSandipan Das 					.gpr[0] = LONG_MAX,
47784022ac1SSandipan Das 				}
47884022ac1SSandipan Das 			}
47984022ac1SSandipan Das 		}
480*44dea178SSandipan Das 	},
481*44dea178SSandipan Das 	{
482*44dea178SSandipan Das 		.mnemonic = "add",
483*44dea178SSandipan Das 		.subtests = {
484*44dea178SSandipan Das 			{
485*44dea178SSandipan Das 				.descr = "RA = LONG_MIN, RB = LONG_MIN",
486*44dea178SSandipan Das 				.instr = TEST_ADD(20, 21, 22),
487*44dea178SSandipan Das 				.regs = {
488*44dea178SSandipan Das 					.gpr[21] = LONG_MIN,
489*44dea178SSandipan Das 					.gpr[22] = LONG_MIN,
490*44dea178SSandipan Das 				}
491*44dea178SSandipan Das 			},
492*44dea178SSandipan Das 			{
493*44dea178SSandipan Das 				.descr = "RA = LONG_MIN, RB = LONG_MAX",
494*44dea178SSandipan Das 				.instr = TEST_ADD(20, 21, 22),
495*44dea178SSandipan Das 				.regs = {
496*44dea178SSandipan Das 					.gpr[21] = LONG_MIN,
497*44dea178SSandipan Das 					.gpr[22] = LONG_MAX,
498*44dea178SSandipan Das 				}
499*44dea178SSandipan Das 			},
500*44dea178SSandipan Das 			{
501*44dea178SSandipan Das 				.descr = "RA = LONG_MAX, RB = LONG_MAX",
502*44dea178SSandipan Das 				.instr = TEST_ADD(20, 21, 22),
503*44dea178SSandipan Das 				.regs = {
504*44dea178SSandipan Das 					.gpr[21] = LONG_MAX,
505*44dea178SSandipan Das 					.gpr[22] = LONG_MAX,
506*44dea178SSandipan Das 				}
507*44dea178SSandipan Das 			},
508*44dea178SSandipan Das 			{
509*44dea178SSandipan Das 				.descr = "RA = ULONG_MAX, RB = ULONG_MAX",
510*44dea178SSandipan Das 				.instr = TEST_ADD(20, 21, 22),
511*44dea178SSandipan Das 				.regs = {
512*44dea178SSandipan Das 					.gpr[21] = ULONG_MAX,
513*44dea178SSandipan Das 					.gpr[22] = ULONG_MAX,
514*44dea178SSandipan Das 				}
515*44dea178SSandipan Das 			},
516*44dea178SSandipan Das 			{
517*44dea178SSandipan Das 				.descr = "RA = ULONG_MAX, RB = 0x1",
518*44dea178SSandipan Das 				.instr = TEST_ADD(20, 21, 22),
519*44dea178SSandipan Das 				.regs = {
520*44dea178SSandipan Das 					.gpr[21] = ULONG_MAX,
521*44dea178SSandipan Das 					.gpr[22] = 0x1,
522*44dea178SSandipan Das 				}
523*44dea178SSandipan Das 			},
524*44dea178SSandipan Das 			{
525*44dea178SSandipan Das 				.descr = "RA = INT_MIN, RB = INT_MIN",
526*44dea178SSandipan Das 				.instr = TEST_ADD(20, 21, 22),
527*44dea178SSandipan Das 				.regs = {
528*44dea178SSandipan Das 					.gpr[21] = INT_MIN,
529*44dea178SSandipan Das 					.gpr[22] = INT_MIN,
530*44dea178SSandipan Das 				}
531*44dea178SSandipan Das 			},
532*44dea178SSandipan Das 			{
533*44dea178SSandipan Das 				.descr = "RA = INT_MIN, RB = INT_MAX",
534*44dea178SSandipan Das 				.instr = TEST_ADD(20, 21, 22),
535*44dea178SSandipan Das 				.regs = {
536*44dea178SSandipan Das 					.gpr[21] = INT_MIN,
537*44dea178SSandipan Das 					.gpr[22] = INT_MAX,
538*44dea178SSandipan Das 				}
539*44dea178SSandipan Das 			},
540*44dea178SSandipan Das 			{
541*44dea178SSandipan Das 				.descr = "RA = INT_MAX, RB = INT_MAX",
542*44dea178SSandipan Das 				.instr = TEST_ADD(20, 21, 22),
543*44dea178SSandipan Das 				.regs = {
544*44dea178SSandipan Das 					.gpr[21] = INT_MAX,
545*44dea178SSandipan Das 					.gpr[22] = INT_MAX,
546*44dea178SSandipan Das 				}
547*44dea178SSandipan Das 			},
548*44dea178SSandipan Das 			{
549*44dea178SSandipan Das 				.descr = "RA = UINT_MAX, RB = UINT_MAX",
550*44dea178SSandipan Das 				.instr = TEST_ADD(20, 21, 22),
551*44dea178SSandipan Das 				.regs = {
552*44dea178SSandipan Das 					.gpr[21] = UINT_MAX,
553*44dea178SSandipan Das 					.gpr[22] = UINT_MAX,
554*44dea178SSandipan Das 				}
555*44dea178SSandipan Das 			},
556*44dea178SSandipan Das 			{
557*44dea178SSandipan Das 				.descr = "RA = UINT_MAX, RB = 0x1",
558*44dea178SSandipan Das 				.instr = TEST_ADD(20, 21, 22),
559*44dea178SSandipan Das 				.regs = {
560*44dea178SSandipan Das 					.gpr[21] = UINT_MAX,
561*44dea178SSandipan Das 					.gpr[22] = 0x1,
562*44dea178SSandipan Das 				}
563*44dea178SSandipan Das 			}
564*44dea178SSandipan Das 		}
565*44dea178SSandipan Das 	},
566*44dea178SSandipan Das 	{
567*44dea178SSandipan Das 		.mnemonic = "add.",
568*44dea178SSandipan Das 		.subtests = {
569*44dea178SSandipan Das 			{
570*44dea178SSandipan Das 				.descr = "RA = LONG_MIN, RB = LONG_MIN",
571*44dea178SSandipan Das 				.flags = IGNORE_CCR,
572*44dea178SSandipan Das 				.instr = TEST_ADD_DOT(20, 21, 22),
573*44dea178SSandipan Das 				.regs = {
574*44dea178SSandipan Das 					.gpr[21] = LONG_MIN,
575*44dea178SSandipan Das 					.gpr[22] = LONG_MIN,
576*44dea178SSandipan Das 				}
577*44dea178SSandipan Das 			},
578*44dea178SSandipan Das 			{
579*44dea178SSandipan Das 				.descr = "RA = LONG_MIN, RB = LONG_MAX",
580*44dea178SSandipan Das 				.instr = TEST_ADD_DOT(20, 21, 22),
581*44dea178SSandipan Das 				.regs = {
582*44dea178SSandipan Das 					.gpr[21] = LONG_MIN,
583*44dea178SSandipan Das 					.gpr[22] = LONG_MAX,
584*44dea178SSandipan Das 				}
585*44dea178SSandipan Das 			},
586*44dea178SSandipan Das 			{
587*44dea178SSandipan Das 				.descr = "RA = LONG_MAX, RB = LONG_MAX",
588*44dea178SSandipan Das 				.flags = IGNORE_CCR,
589*44dea178SSandipan Das 				.instr = TEST_ADD_DOT(20, 21, 22),
590*44dea178SSandipan Das 				.regs = {
591*44dea178SSandipan Das 					.gpr[21] = LONG_MAX,
592*44dea178SSandipan Das 					.gpr[22] = LONG_MAX,
593*44dea178SSandipan Das 				}
594*44dea178SSandipan Das 			},
595*44dea178SSandipan Das 			{
596*44dea178SSandipan Das 				.descr = "RA = ULONG_MAX, RB = ULONG_MAX",
597*44dea178SSandipan Das 				.instr = TEST_ADD_DOT(20, 21, 22),
598*44dea178SSandipan Das 				.regs = {
599*44dea178SSandipan Das 					.gpr[21] = ULONG_MAX,
600*44dea178SSandipan Das 					.gpr[22] = ULONG_MAX,
601*44dea178SSandipan Das 				}
602*44dea178SSandipan Das 			},
603*44dea178SSandipan Das 			{
604*44dea178SSandipan Das 				.descr = "RA = ULONG_MAX, RB = 0x1",
605*44dea178SSandipan Das 				.instr = TEST_ADD_DOT(20, 21, 22),
606*44dea178SSandipan Das 				.regs = {
607*44dea178SSandipan Das 					.gpr[21] = ULONG_MAX,
608*44dea178SSandipan Das 					.gpr[22] = 0x1,
609*44dea178SSandipan Das 				}
610*44dea178SSandipan Das 			},
611*44dea178SSandipan Das 			{
612*44dea178SSandipan Das 				.descr = "RA = INT_MIN, RB = INT_MIN",
613*44dea178SSandipan Das 				.instr = TEST_ADD_DOT(20, 21, 22),
614*44dea178SSandipan Das 				.regs = {
615*44dea178SSandipan Das 					.gpr[21] = INT_MIN,
616*44dea178SSandipan Das 					.gpr[22] = INT_MIN,
617*44dea178SSandipan Das 				}
618*44dea178SSandipan Das 			},
619*44dea178SSandipan Das 			{
620*44dea178SSandipan Das 				.descr = "RA = INT_MIN, RB = INT_MAX",
621*44dea178SSandipan Das 				.instr = TEST_ADD_DOT(20, 21, 22),
622*44dea178SSandipan Das 				.regs = {
623*44dea178SSandipan Das 					.gpr[21] = INT_MIN,
624*44dea178SSandipan Das 					.gpr[22] = INT_MAX,
625*44dea178SSandipan Das 				}
626*44dea178SSandipan Das 			},
627*44dea178SSandipan Das 			{
628*44dea178SSandipan Das 				.descr = "RA = INT_MAX, RB = INT_MAX",
629*44dea178SSandipan Das 				.instr = TEST_ADD_DOT(20, 21, 22),
630*44dea178SSandipan Das 				.regs = {
631*44dea178SSandipan Das 					.gpr[21] = INT_MAX,
632*44dea178SSandipan Das 					.gpr[22] = INT_MAX,
633*44dea178SSandipan Das 				}
634*44dea178SSandipan Das 			},
635*44dea178SSandipan Das 			{
636*44dea178SSandipan Das 				.descr = "RA = UINT_MAX, RB = UINT_MAX",
637*44dea178SSandipan Das 				.instr = TEST_ADD_DOT(20, 21, 22),
638*44dea178SSandipan Das 				.regs = {
639*44dea178SSandipan Das 					.gpr[21] = UINT_MAX,
640*44dea178SSandipan Das 					.gpr[22] = UINT_MAX,
641*44dea178SSandipan Das 				}
642*44dea178SSandipan Das 			},
643*44dea178SSandipan Das 			{
644*44dea178SSandipan Das 				.descr = "RA = UINT_MAX, RB = 0x1",
645*44dea178SSandipan Das 				.instr = TEST_ADD_DOT(20, 21, 22),
646*44dea178SSandipan Das 				.regs = {
647*44dea178SSandipan Das 					.gpr[21] = UINT_MAX,
648*44dea178SSandipan Das 					.gpr[22] = 0x1,
649*44dea178SSandipan Das 				}
650*44dea178SSandipan Das 			}
651*44dea178SSandipan Das 		}
65284022ac1SSandipan Das 	}
65384022ac1SSandipan Das };
65484022ac1SSandipan Das 
65584022ac1SSandipan Das static int __init emulate_compute_instr(struct pt_regs *regs,
65684022ac1SSandipan Das 					unsigned int instr)
65784022ac1SSandipan Das {
65884022ac1SSandipan Das 	struct instruction_op op;
65984022ac1SSandipan Das 
66084022ac1SSandipan Das 	if (!regs || !instr)
66184022ac1SSandipan Das 		return -EINVAL;
66284022ac1SSandipan Das 
66384022ac1SSandipan Das 	if (analyse_instr(&op, regs, instr) != 1 ||
66484022ac1SSandipan Das 	    GETTYPE(op.type) != COMPUTE) {
66584022ac1SSandipan Das 		pr_info("emulation failed, instruction = 0x%08x\n", instr);
66684022ac1SSandipan Das 		return -EFAULT;
66784022ac1SSandipan Das 	}
66884022ac1SSandipan Das 
66984022ac1SSandipan Das 	emulate_update_regs(regs, &op);
67084022ac1SSandipan Das 	return 0;
67184022ac1SSandipan Das }
67284022ac1SSandipan Das 
67384022ac1SSandipan Das static int __init execute_compute_instr(struct pt_regs *regs,
67484022ac1SSandipan Das 					unsigned int instr)
67584022ac1SSandipan Das {
67684022ac1SSandipan Das 	extern int exec_instr(struct pt_regs *regs);
67784022ac1SSandipan Das 	extern s32 patch__exec_instr;
67884022ac1SSandipan Das 
67984022ac1SSandipan Das 	if (!regs || !instr)
68084022ac1SSandipan Das 		return -EINVAL;
68184022ac1SSandipan Das 
68284022ac1SSandipan Das 	/* Patch the NOP with the actual instruction */
68384022ac1SSandipan Das 	patch_instruction_site(&patch__exec_instr, instr);
68484022ac1SSandipan Das 	if (exec_instr(regs)) {
68584022ac1SSandipan Das 		pr_info("execution failed, instruction = 0x%08x\n", instr);
68684022ac1SSandipan Das 		return -EFAULT;
68784022ac1SSandipan Das 	}
68884022ac1SSandipan Das 
68984022ac1SSandipan Das 	return 0;
69084022ac1SSandipan Das }
69184022ac1SSandipan Das 
69284022ac1SSandipan Das #define gpr_mismatch(gprn, exp, got)	\
69384022ac1SSandipan Das 	pr_info("GPR%u mismatch, exp = 0x%016lx, got = 0x%016lx\n",	\
69484022ac1SSandipan Das 		gprn, exp, got)
69584022ac1SSandipan Das 
69684022ac1SSandipan Das #define reg_mismatch(name, exp, got)	\
69784022ac1SSandipan Das 	pr_info("%s mismatch, exp = 0x%016lx, got = 0x%016lx\n",	\
69884022ac1SSandipan Das 		name, exp, got)
69984022ac1SSandipan Das 
70084022ac1SSandipan Das static void __init run_tests_compute(void)
70184022ac1SSandipan Das {
70284022ac1SSandipan Das 	unsigned long flags;
70384022ac1SSandipan Das 	struct compute_test *test;
70484022ac1SSandipan Das 	struct pt_regs *regs, exp, got;
70584022ac1SSandipan Das 	unsigned int i, j, k, instr;
70684022ac1SSandipan Das 	bool ignore_gpr, ignore_xer, ignore_ccr, passed;
70784022ac1SSandipan Das 
70884022ac1SSandipan Das 	for (i = 0; i < ARRAY_SIZE(compute_tests); i++) {
70984022ac1SSandipan Das 		test = &compute_tests[i];
71084022ac1SSandipan Das 
71184022ac1SSandipan Das 		for (j = 0; j < MAX_SUBTESTS && test->subtests[j].descr; j++) {
71284022ac1SSandipan Das 			instr = test->subtests[j].instr;
71384022ac1SSandipan Das 			flags = test->subtests[j].flags;
71484022ac1SSandipan Das 			regs = &test->subtests[j].regs;
71584022ac1SSandipan Das 			ignore_xer = flags & IGNORE_XER;
71684022ac1SSandipan Das 			ignore_ccr = flags & IGNORE_CCR;
71784022ac1SSandipan Das 			passed = true;
71884022ac1SSandipan Das 
71984022ac1SSandipan Das 			memcpy(&exp, regs, sizeof(struct pt_regs));
72084022ac1SSandipan Das 			memcpy(&got, regs, sizeof(struct pt_regs));
72184022ac1SSandipan Das 
72284022ac1SSandipan Das 			/*
72384022ac1SSandipan Das 			 * Set a compatible MSR value explicitly to ensure
72484022ac1SSandipan Das 			 * that XER and CR bits are updated appropriately
72584022ac1SSandipan Das 			 */
72684022ac1SSandipan Das 			exp.msr = MSR_KERNEL;
72784022ac1SSandipan Das 			got.msr = MSR_KERNEL;
72884022ac1SSandipan Das 
72984022ac1SSandipan Das 			if (emulate_compute_instr(&got, instr) ||
73084022ac1SSandipan Das 			    execute_compute_instr(&exp, instr)) {
73184022ac1SSandipan Das 				passed = false;
73284022ac1SSandipan Das 				goto print;
73384022ac1SSandipan Das 			}
73484022ac1SSandipan Das 
73584022ac1SSandipan Das 			/* Verify GPR values */
73684022ac1SSandipan Das 			for (k = 0; k < 32; k++) {
73784022ac1SSandipan Das 				ignore_gpr = flags & IGNORE_GPR(k);
73884022ac1SSandipan Das 				if (!ignore_gpr && exp.gpr[k] != got.gpr[k]) {
73984022ac1SSandipan Das 					passed = false;
74084022ac1SSandipan Das 					gpr_mismatch(k, exp.gpr[k], got.gpr[k]);
74184022ac1SSandipan Das 				}
74284022ac1SSandipan Das 			}
74384022ac1SSandipan Das 
74484022ac1SSandipan Das 			/* Verify LR value */
74584022ac1SSandipan Das 			if (exp.link != got.link) {
74684022ac1SSandipan Das 				passed = false;
74784022ac1SSandipan Das 				reg_mismatch("LR", exp.link, got.link);
74884022ac1SSandipan Das 			}
74984022ac1SSandipan Das 
75084022ac1SSandipan Das 			/* Verify XER value */
75184022ac1SSandipan Das 			if (!ignore_xer && exp.xer != got.xer) {
75284022ac1SSandipan Das 				passed = false;
75384022ac1SSandipan Das 				reg_mismatch("XER", exp.xer, got.xer);
75484022ac1SSandipan Das 			}
75584022ac1SSandipan Das 
75684022ac1SSandipan Das 			/* Verify CR value */
75784022ac1SSandipan Das 			if (!ignore_ccr && exp.ccr != got.ccr) {
75884022ac1SSandipan Das 				passed = false;
75984022ac1SSandipan Das 				reg_mismatch("CR", exp.ccr, got.ccr);
76084022ac1SSandipan Das 			}
76184022ac1SSandipan Das 
76284022ac1SSandipan Das print:
76384022ac1SSandipan Das 			show_result_with_descr(test->mnemonic,
76484022ac1SSandipan Das 					       test->subtests[j].descr,
76584022ac1SSandipan Das 					       passed ? "PASS" : "FAIL");
76684022ac1SSandipan Das 		}
76784022ac1SSandipan Das 	}
76884022ac1SSandipan Das }
76984022ac1SSandipan Das 
77084022ac1SSandipan Das static int __init test_emulate_step(void)
77184022ac1SSandipan Das {
77284022ac1SSandipan Das 	printk(KERN_INFO "Running instruction emulation self-tests ...\n");
77384022ac1SSandipan Das 	run_tests_load_store();
77484022ac1SSandipan Das 	run_tests_compute();
7754ceae137SRavi Bangoria 
7764ceae137SRavi Bangoria 	return 0;
7774ceae137SRavi Bangoria }
7784ceae137SRavi Bangoria late_initcall(test_emulate_step);
779