1// SPDX-License-Identifier: GPL-2.0-or-later
2/*
3 * Simple sanity tests for instruction emulation infrastructure.
4 *
5 * Copyright IBM Corp. 2016
6 */
7
8#define pr_fmt(fmt) "emulate_step_test: " fmt
9
10#include <linux/ptrace.h>
11#include <asm/cpu_has_feature.h>
12#include <asm/sstep.h>
13#include <asm/ppc-opcode.h>
14#include <asm/code-patching.h>
15#include <asm/inst.h>
16
17#define MAX_SUBTESTS	16
18
19#define IGNORE_GPR(n)	(0x1UL << (n))
20#define IGNORE_XER	(0x1UL << 32)
21#define IGNORE_CCR	(0x1UL << 33)
22#define NEGATIVE_TEST	(0x1UL << 63)
23
24#define TEST_PLD(r, base, i, pr) \
25	ppc_inst_prefix(PPC_PREFIX_8LS | __PPC_PRFX_R(pr) | IMM_H(i), \
26			PPC_INST_PLD | ___PPC_RT(r) | ___PPC_RA(base) | IMM_L(i))
27
28#define TEST_PLWZ(r, base, i, pr) \
29	ppc_inst_prefix(PPC_PREFIX_MLS | __PPC_PRFX_R(pr) | IMM_H(i), \
30			PPC_RAW_LWZ(r, base, i))
31
32#define TEST_PSTD(r, base, i, pr) \
33	ppc_inst_prefix(PPC_PREFIX_8LS | __PPC_PRFX_R(pr) | IMM_H(i), \
34			PPC_INST_PSTD | ___PPC_RT(r) | ___PPC_RA(base) | IMM_L(i))
35
36#define TEST_PLFS(r, base, i, pr) \
37	ppc_inst_prefix(PPC_PREFIX_MLS | __PPC_PRFX_R(pr) | IMM_H(i), \
38			PPC_INST_LFS | ___PPC_RT(r) | ___PPC_RA(base) | IMM_L(i))
39
40#define TEST_PSTFS(r, base, i, pr) \
41	ppc_inst_prefix(PPC_PREFIX_MLS | __PPC_PRFX_R(pr) | IMM_H(i), \
42			PPC_INST_STFS | ___PPC_RT(r) | ___PPC_RA(base) | IMM_L(i))
43
44#define TEST_PLFD(r, base, i, pr) \
45	ppc_inst_prefix(PPC_PREFIX_MLS | __PPC_PRFX_R(pr) | IMM_H(i), \
46			PPC_INST_LFD | ___PPC_RT(r) | ___PPC_RA(base) | IMM_L(i))
47
48#define TEST_PSTFD(r, base, i, pr) \
49	ppc_inst_prefix(PPC_PREFIX_MLS | __PPC_PRFX_R(pr) | IMM_H(i), \
50			PPC_INST_STFD | ___PPC_RT(r) | ___PPC_RA(base) | IMM_L(i))
51
52#define TEST_PADDI(t, a, i, pr) \
53	ppc_inst_prefix(PPC_PREFIX_MLS | __PPC_PRFX_R(pr) | IMM_H(i), \
54			PPC_RAW_ADDI(t, a, i))
55
56
57static void __init init_pt_regs(struct pt_regs *regs)
58{
59	static unsigned long msr;
60	static bool msr_cached;
61
62	memset(regs, 0, sizeof(struct pt_regs));
63
64	if (likely(msr_cached)) {
65		regs->msr = msr;
66		return;
67	}
68
69	asm volatile("mfmsr %0" : "=r"(regs->msr));
70
71	regs->msr |= MSR_FP;
72	regs->msr |= MSR_VEC;
73	regs->msr |= MSR_VSX;
74
75	msr = regs->msr;
76	msr_cached = true;
77}
78
79static void __init show_result(char *mnemonic, char *result)
80{
81	pr_info("%-14s : %s\n", mnemonic, result);
82}
83
84static void __init show_result_with_descr(char *mnemonic, char *descr,
85					  char *result)
86{
87	pr_info("%-14s : %-50s %s\n", mnemonic, descr, result);
88}
89
90static void __init test_ld(void)
91{
92	struct pt_regs regs;
93	unsigned long a = 0x23;
94	int stepped = -1;
95
96	init_pt_regs(&regs);
97	regs.gpr[3] = (unsigned long) &a;
98
99	/* ld r5, 0(r3) */
100	stepped = emulate_step(&regs, ppc_inst(PPC_RAW_LD(5, 3, 0)));
101
102	if (stepped == 1 && regs.gpr[5] == a)
103		show_result("ld", "PASS");
104	else
105		show_result("ld", "FAIL");
106}
107
108static void __init test_pld(void)
109{
110	struct pt_regs regs;
111	unsigned long a = 0x23;
112	int stepped = -1;
113
114	if (!cpu_has_feature(CPU_FTR_ARCH_31)) {
115		show_result("pld", "SKIP (!CPU_FTR_ARCH_31)");
116		return;
117	}
118
119	init_pt_regs(&regs);
120	regs.gpr[3] = (unsigned long)&a;
121
122	/* pld r5, 0(r3), 0 */
123	stepped = emulate_step(&regs, TEST_PLD(5, 3, 0, 0));
124
125	if (stepped == 1 && regs.gpr[5] == a)
126		show_result("pld", "PASS");
127	else
128		show_result("pld", "FAIL");
129}
130
131static void __init test_lwz(void)
132{
133	struct pt_regs regs;
134	unsigned int a = 0x4545;
135	int stepped = -1;
136
137	init_pt_regs(&regs);
138	regs.gpr[3] = (unsigned long) &a;
139
140	/* lwz r5, 0(r3) */
141	stepped = emulate_step(&regs, ppc_inst(PPC_RAW_LWZ(5, 3, 0)));
142
143	if (stepped == 1 && regs.gpr[5] == a)
144		show_result("lwz", "PASS");
145	else
146		show_result("lwz", "FAIL");
147}
148
149static void __init test_plwz(void)
150{
151	struct pt_regs regs;
152	unsigned int a = 0x4545;
153	int stepped = -1;
154
155	if (!cpu_has_feature(CPU_FTR_ARCH_31)) {
156		show_result("plwz", "SKIP (!CPU_FTR_ARCH_31)");
157		return;
158	}
159
160	init_pt_regs(&regs);
161	regs.gpr[3] = (unsigned long)&a;
162
163	/* plwz r5, 0(r3), 0 */
164
165	stepped = emulate_step(&regs, TEST_PLWZ(5, 3, 0, 0));
166
167	if (stepped == 1 && regs.gpr[5] == a)
168		show_result("plwz", "PASS");
169	else
170		show_result("plwz", "FAIL");
171}
172
173static void __init test_lwzx(void)
174{
175	struct pt_regs regs;
176	unsigned int a[3] = {0x0, 0x0, 0x1234};
177	int stepped = -1;
178
179	init_pt_regs(&regs);
180	regs.gpr[3] = (unsigned long) a;
181	regs.gpr[4] = 8;
182	regs.gpr[5] = 0x8765;
183
184	/* lwzx r5, r3, r4 */
185	stepped = emulate_step(&regs, ppc_inst(PPC_RAW_LWZX(5, 3, 4)));
186	if (stepped == 1 && regs.gpr[5] == a[2])
187		show_result("lwzx", "PASS");
188	else
189		show_result("lwzx", "FAIL");
190}
191
192static void __init test_std(void)
193{
194	struct pt_regs regs;
195	unsigned long a = 0x1234;
196	int stepped = -1;
197
198	init_pt_regs(&regs);
199	regs.gpr[3] = (unsigned long) &a;
200	regs.gpr[5] = 0x5678;
201
202	/* std r5, 0(r3) */
203	stepped = emulate_step(&regs, ppc_inst(PPC_RAW_STD(5, 3, 0)));
204	if (stepped == 1 && regs.gpr[5] == a)
205		show_result("std", "PASS");
206	else
207		show_result("std", "FAIL");
208}
209
210static void __init test_pstd(void)
211{
212	struct pt_regs regs;
213	unsigned long a = 0x1234;
214	int stepped = -1;
215
216	if (!cpu_has_feature(CPU_FTR_ARCH_31)) {
217		show_result("pstd", "SKIP (!CPU_FTR_ARCH_31)");
218		return;
219	}
220
221	init_pt_regs(&regs);
222	regs.gpr[3] = (unsigned long)&a;
223	regs.gpr[5] = 0x5678;
224
225	/* pstd r5, 0(r3), 0 */
226	stepped = emulate_step(&regs, TEST_PSTD(5, 3, 0, 0));
227	if (stepped == 1 || regs.gpr[5] == a)
228		show_result("pstd", "PASS");
229	else
230		show_result("pstd", "FAIL");
231}
232
233static void __init test_ldarx_stdcx(void)
234{
235	struct pt_regs regs;
236	unsigned long a = 0x1234;
237	int stepped = -1;
238	unsigned long cr0_eq = 0x1 << 29; /* eq bit of CR0 */
239
240	init_pt_regs(&regs);
241	asm volatile("mfcr %0" : "=r"(regs.ccr));
242
243
244	/*** ldarx ***/
245
246	regs.gpr[3] = (unsigned long) &a;
247	regs.gpr[4] = 0;
248	regs.gpr[5] = 0x5678;
249
250	/* ldarx r5, r3, r4, 0 */
251	stepped = emulate_step(&regs, ppc_inst(PPC_RAW_LDARX(5, 3, 4, 0)));
252
253	/*
254	 * Don't touch 'a' here. Touching 'a' can do Load/store
255	 * of 'a' which result in failure of subsequent stdcx.
256	 * Instead, use hardcoded value for comparison.
257	 */
258	if (stepped <= 0 || regs.gpr[5] != 0x1234) {
259		show_result("ldarx / stdcx.", "FAIL (ldarx)");
260		return;
261	}
262
263
264	/*** stdcx. ***/
265
266	regs.gpr[5] = 0x9ABC;
267
268	/* stdcx. r5, r3, r4 */
269	stepped = emulate_step(&regs, ppc_inst(PPC_RAW_STDCX(5, 3, 4)));
270
271	/*
272	 * Two possible scenarios that indicates successful emulation
273	 * of stdcx. :
274	 *  1. Reservation is active and store is performed. In this
275	 *     case cr0.eq bit will be set to 1.
276	 *  2. Reservation is not active and store is not performed.
277	 *     In this case cr0.eq bit will be set to 0.
278	 */
279	if (stepped == 1 && ((regs.gpr[5] == a && (regs.ccr & cr0_eq))
280			|| (regs.gpr[5] != a && !(regs.ccr & cr0_eq))))
281		show_result("ldarx / stdcx.", "PASS");
282	else
283		show_result("ldarx / stdcx.", "FAIL (stdcx.)");
284}
285
286#ifdef CONFIG_PPC_FPU
287static void __init test_lfsx_stfsx(void)
288{
289	struct pt_regs regs;
290	union {
291		float a;
292		int b;
293	} c;
294	int cached_b;
295	int stepped = -1;
296
297	init_pt_regs(&regs);
298
299
300	/*** lfsx ***/
301
302	c.a = 123.45;
303	cached_b = c.b;
304
305	regs.gpr[3] = (unsigned long) &c.a;
306	regs.gpr[4] = 0;
307
308	/* lfsx frt10, r3, r4 */
309	stepped = emulate_step(&regs, ppc_inst(PPC_RAW_LFSX(10, 3, 4)));
310
311	if (stepped == 1)
312		show_result("lfsx", "PASS");
313	else
314		show_result("lfsx", "FAIL");
315
316
317	/*** stfsx ***/
318
319	c.a = 678.91;
320
321	/* stfsx frs10, r3, r4 */
322	stepped = emulate_step(&regs, ppc_inst(PPC_RAW_STFSX(10, 3, 4)));
323
324	if (stepped == 1 && c.b == cached_b)
325		show_result("stfsx", "PASS");
326	else
327		show_result("stfsx", "FAIL");
328}
329
330static void __init test_plfs_pstfs(void)
331{
332	struct pt_regs regs;
333	union {
334		float a;
335		int b;
336	} c;
337	int cached_b;
338	int stepped = -1;
339
340	if (!cpu_has_feature(CPU_FTR_ARCH_31)) {
341		show_result("pld", "SKIP (!CPU_FTR_ARCH_31)");
342		return;
343	}
344
345	init_pt_regs(&regs);
346
347
348	/*** plfs ***/
349
350	c.a = 123.45;
351	cached_b = c.b;
352
353	regs.gpr[3] = (unsigned long)&c.a;
354
355	/* plfs frt10, 0(r3), 0  */
356	stepped = emulate_step(&regs, TEST_PLFS(10, 3, 0, 0));
357
358	if (stepped == 1)
359		show_result("plfs", "PASS");
360	else
361		show_result("plfs", "FAIL");
362
363
364	/*** pstfs ***/
365
366	c.a = 678.91;
367
368	/* pstfs frs10, 0(r3), 0 */
369	stepped = emulate_step(&regs, TEST_PSTFS(10, 3, 0, 0));
370
371	if (stepped == 1 && c.b == cached_b)
372		show_result("pstfs", "PASS");
373	else
374		show_result("pstfs", "FAIL");
375}
376
377static void __init test_lfdx_stfdx(void)
378{
379	struct pt_regs regs;
380	union {
381		double a;
382		long b;
383	} c;
384	long cached_b;
385	int stepped = -1;
386
387	init_pt_regs(&regs);
388
389
390	/*** lfdx ***/
391
392	c.a = 123456.78;
393	cached_b = c.b;
394
395	regs.gpr[3] = (unsigned long) &c.a;
396	regs.gpr[4] = 0;
397
398	/* lfdx frt10, r3, r4 */
399	stepped = emulate_step(&regs, ppc_inst(PPC_RAW_LFDX(10, 3, 4)));
400
401	if (stepped == 1)
402		show_result("lfdx", "PASS");
403	else
404		show_result("lfdx", "FAIL");
405
406
407	/*** stfdx ***/
408
409	c.a = 987654.32;
410
411	/* stfdx frs10, r3, r4 */
412	stepped = emulate_step(&regs, ppc_inst(PPC_RAW_STFDX(10, 3, 4)));
413
414	if (stepped == 1 && c.b == cached_b)
415		show_result("stfdx", "PASS");
416	else
417		show_result("stfdx", "FAIL");
418}
419
420static void __init test_plfd_pstfd(void)
421{
422	struct pt_regs regs;
423	union {
424		double a;
425		long b;
426	} c;
427	long cached_b;
428	int stepped = -1;
429
430	if (!cpu_has_feature(CPU_FTR_ARCH_31)) {
431		show_result("pld", "SKIP (!CPU_FTR_ARCH_31)");
432		return;
433	}
434
435	init_pt_regs(&regs);
436
437
438	/*** plfd ***/
439
440	c.a = 123456.78;
441	cached_b = c.b;
442
443	regs.gpr[3] = (unsigned long)&c.a;
444
445	/* plfd frt10, 0(r3), 0 */
446	stepped = emulate_step(&regs, TEST_PLFD(10, 3, 0, 0));
447
448	if (stepped == 1)
449		show_result("plfd", "PASS");
450	else
451		show_result("plfd", "FAIL");
452
453
454	/*** pstfd ***/
455
456	c.a = 987654.32;
457
458	/* pstfd frs10, 0(r3), 0 */
459	stepped = emulate_step(&regs, TEST_PSTFD(10, 3, 0, 0));
460
461	if (stepped == 1 && c.b == cached_b)
462		show_result("pstfd", "PASS");
463	else
464		show_result("pstfd", "FAIL");
465}
466#else
467static void __init test_lfsx_stfsx(void)
468{
469	show_result("lfsx", "SKIP (CONFIG_PPC_FPU is not set)");
470	show_result("stfsx", "SKIP (CONFIG_PPC_FPU is not set)");
471}
472
473static void __init test_plfs_pstfs(void)
474{
475	show_result("plfs", "SKIP (CONFIG_PPC_FPU is not set)");
476	show_result("pstfs", "SKIP (CONFIG_PPC_FPU is not set)");
477}
478
479static void __init test_lfdx_stfdx(void)
480{
481	show_result("lfdx", "SKIP (CONFIG_PPC_FPU is not set)");
482	show_result("stfdx", "SKIP (CONFIG_PPC_FPU is not set)");
483}
484
485static void __init test_plfd_pstfd(void)
486{
487	show_result("plfd", "SKIP (CONFIG_PPC_FPU is not set)");
488	show_result("pstfd", "SKIP (CONFIG_PPC_FPU is not set)");
489}
490#endif /* CONFIG_PPC_FPU */
491
492#ifdef CONFIG_ALTIVEC
493static void __init test_lvx_stvx(void)
494{
495	struct pt_regs regs;
496	union {
497		vector128 a;
498		u32 b[4];
499	} c;
500	u32 cached_b[4];
501	int stepped = -1;
502
503	init_pt_regs(&regs);
504
505
506	/*** lvx ***/
507
508	cached_b[0] = c.b[0] = 923745;
509	cached_b[1] = c.b[1] = 2139478;
510	cached_b[2] = c.b[2] = 9012;
511	cached_b[3] = c.b[3] = 982134;
512
513	regs.gpr[3] = (unsigned long) &c.a;
514	regs.gpr[4] = 0;
515
516	/* lvx vrt10, r3, r4 */
517	stepped = emulate_step(&regs, ppc_inst(PPC_RAW_LVX(10, 3, 4)));
518
519	if (stepped == 1)
520		show_result("lvx", "PASS");
521	else
522		show_result("lvx", "FAIL");
523
524
525	/*** stvx ***/
526
527	c.b[0] = 4987513;
528	c.b[1] = 84313948;
529	c.b[2] = 71;
530	c.b[3] = 498532;
531
532	/* stvx vrs10, r3, r4 */
533	stepped = emulate_step(&regs, ppc_inst(PPC_RAW_STVX(10, 3, 4)));
534
535	if (stepped == 1 && cached_b[0] == c.b[0] && cached_b[1] == c.b[1] &&
536	    cached_b[2] == c.b[2] && cached_b[3] == c.b[3])
537		show_result("stvx", "PASS");
538	else
539		show_result("stvx", "FAIL");
540}
541#else
542static void __init test_lvx_stvx(void)
543{
544	show_result("lvx", "SKIP (CONFIG_ALTIVEC is not set)");
545	show_result("stvx", "SKIP (CONFIG_ALTIVEC is not set)");
546}
547#endif /* CONFIG_ALTIVEC */
548
549#ifdef CONFIG_VSX
550static void __init test_lxvd2x_stxvd2x(void)
551{
552	struct pt_regs regs;
553	union {
554		vector128 a;
555		u32 b[4];
556	} c;
557	u32 cached_b[4];
558	int stepped = -1;
559
560	init_pt_regs(&regs);
561
562
563	/*** lxvd2x ***/
564
565	cached_b[0] = c.b[0] = 18233;
566	cached_b[1] = c.b[1] = 34863571;
567	cached_b[2] = c.b[2] = 834;
568	cached_b[3] = c.b[3] = 6138911;
569
570	regs.gpr[3] = (unsigned long) &c.a;
571	regs.gpr[4] = 0;
572
573	/* lxvd2x vsr39, r3, r4 */
574	stepped = emulate_step(&regs, ppc_inst(PPC_RAW_LXVD2X(39, R3, R4)));
575
576	if (stepped == 1 && cpu_has_feature(CPU_FTR_VSX)) {
577		show_result("lxvd2x", "PASS");
578	} else {
579		if (!cpu_has_feature(CPU_FTR_VSX))
580			show_result("lxvd2x", "PASS (!CPU_FTR_VSX)");
581		else
582			show_result("lxvd2x", "FAIL");
583	}
584
585
586	/*** stxvd2x ***/
587
588	c.b[0] = 21379463;
589	c.b[1] = 87;
590	c.b[2] = 374234;
591	c.b[3] = 4;
592
593	/* stxvd2x vsr39, r3, r4 */
594	stepped = emulate_step(&regs, ppc_inst(PPC_RAW_STXVD2X(39, R3, R4)));
595
596	if (stepped == 1 && cached_b[0] == c.b[0] && cached_b[1] == c.b[1] &&
597	    cached_b[2] == c.b[2] && cached_b[3] == c.b[3] &&
598	    cpu_has_feature(CPU_FTR_VSX)) {
599		show_result("stxvd2x", "PASS");
600	} else {
601		if (!cpu_has_feature(CPU_FTR_VSX))
602			show_result("stxvd2x", "PASS (!CPU_FTR_VSX)");
603		else
604			show_result("stxvd2x", "FAIL");
605	}
606}
607#else
608static void __init test_lxvd2x_stxvd2x(void)
609{
610	show_result("lxvd2x", "SKIP (CONFIG_VSX is not set)");
611	show_result("stxvd2x", "SKIP (CONFIG_VSX is not set)");
612}
613#endif /* CONFIG_VSX */
614
615static void __init run_tests_load_store(void)
616{
617	test_ld();
618	test_pld();
619	test_lwz();
620	test_plwz();
621	test_lwzx();
622	test_std();
623	test_pstd();
624	test_ldarx_stdcx();
625	test_lfsx_stfsx();
626	test_plfs_pstfs();
627	test_lfdx_stfdx();
628	test_plfd_pstfd();
629	test_lvx_stvx();
630	test_lxvd2x_stxvd2x();
631}
632
633struct compute_test {
634	char *mnemonic;
635	unsigned long cpu_feature;
636	struct {
637		char *descr;
638		unsigned long flags;
639		struct ppc_inst instr;
640		struct pt_regs regs;
641	} subtests[MAX_SUBTESTS + 1];
642};
643
644/* Extreme values for si0||si1 (the MLS:D-form 34 bit immediate field) */
645#define SI_MIN BIT(33)
646#define SI_MAX (BIT(33) - 1)
647#define SI_UMAX (BIT(34) - 1)
648
649static struct compute_test compute_tests[] = {
650	{
651		.mnemonic = "nop",
652		.subtests = {
653			{
654				.descr = "R0 = LONG_MAX",
655				.instr = ppc_inst(PPC_INST_NOP),
656				.regs = {
657					.gpr[0] = LONG_MAX,
658				}
659			}
660		}
661	},
662	{
663		.mnemonic = "add",
664		.subtests = {
665			{
666				.descr = "RA = LONG_MIN, RB = LONG_MIN",
667				.instr = ppc_inst(PPC_RAW_ADD(20, 21, 22)),
668				.regs = {
669					.gpr[21] = LONG_MIN,
670					.gpr[22] = LONG_MIN,
671				}
672			},
673			{
674				.descr = "RA = LONG_MIN, RB = LONG_MAX",
675				.instr = ppc_inst(PPC_RAW_ADD(20, 21, 22)),
676				.regs = {
677					.gpr[21] = LONG_MIN,
678					.gpr[22] = LONG_MAX,
679				}
680			},
681			{
682				.descr = "RA = LONG_MAX, RB = LONG_MAX",
683				.instr = ppc_inst(PPC_RAW_ADD(20, 21, 22)),
684				.regs = {
685					.gpr[21] = LONG_MAX,
686					.gpr[22] = LONG_MAX,
687				}
688			},
689			{
690				.descr = "RA = ULONG_MAX, RB = ULONG_MAX",
691				.instr = ppc_inst(PPC_RAW_ADD(20, 21, 22)),
692				.regs = {
693					.gpr[21] = ULONG_MAX,
694					.gpr[22] = ULONG_MAX,
695				}
696			},
697			{
698				.descr = "RA = ULONG_MAX, RB = 0x1",
699				.instr = ppc_inst(PPC_RAW_ADD(20, 21, 22)),
700				.regs = {
701					.gpr[21] = ULONG_MAX,
702					.gpr[22] = 0x1,
703				}
704			},
705			{
706				.descr = "RA = INT_MIN, RB = INT_MIN",
707				.instr = ppc_inst(PPC_RAW_ADD(20, 21, 22)),
708				.regs = {
709					.gpr[21] = INT_MIN,
710					.gpr[22] = INT_MIN,
711				}
712			},
713			{
714				.descr = "RA = INT_MIN, RB = INT_MAX",
715				.instr = ppc_inst(PPC_RAW_ADD(20, 21, 22)),
716				.regs = {
717					.gpr[21] = INT_MIN,
718					.gpr[22] = INT_MAX,
719				}
720			},
721			{
722				.descr = "RA = INT_MAX, RB = INT_MAX",
723				.instr = ppc_inst(PPC_RAW_ADD(20, 21, 22)),
724				.regs = {
725					.gpr[21] = INT_MAX,
726					.gpr[22] = INT_MAX,
727				}
728			},
729			{
730				.descr = "RA = UINT_MAX, RB = UINT_MAX",
731				.instr = ppc_inst(PPC_RAW_ADD(20, 21, 22)),
732				.regs = {
733					.gpr[21] = UINT_MAX,
734					.gpr[22] = UINT_MAX,
735				}
736			},
737			{
738				.descr = "RA = UINT_MAX, RB = 0x1",
739				.instr = ppc_inst(PPC_RAW_ADD(20, 21, 22)),
740				.regs = {
741					.gpr[21] = UINT_MAX,
742					.gpr[22] = 0x1,
743				}
744			}
745		}
746	},
747	{
748		.mnemonic = "add.",
749		.subtests = {
750			{
751				.descr = "RA = LONG_MIN, RB = LONG_MIN",
752				.flags = IGNORE_CCR,
753				.instr = ppc_inst(PPC_RAW_ADD_DOT(20, 21, 22)),
754				.regs = {
755					.gpr[21] = LONG_MIN,
756					.gpr[22] = LONG_MIN,
757				}
758			},
759			{
760				.descr = "RA = LONG_MIN, RB = LONG_MAX",
761				.instr = ppc_inst(PPC_RAW_ADD_DOT(20, 21, 22)),
762				.regs = {
763					.gpr[21] = LONG_MIN,
764					.gpr[22] = LONG_MAX,
765				}
766			},
767			{
768				.descr = "RA = LONG_MAX, RB = LONG_MAX",
769				.flags = IGNORE_CCR,
770				.instr = ppc_inst(PPC_RAW_ADD_DOT(20, 21, 22)),
771				.regs = {
772					.gpr[21] = LONG_MAX,
773					.gpr[22] = LONG_MAX,
774				}
775			},
776			{
777				.descr = "RA = ULONG_MAX, RB = ULONG_MAX",
778				.instr = ppc_inst(PPC_RAW_ADD_DOT(20, 21, 22)),
779				.regs = {
780					.gpr[21] = ULONG_MAX,
781					.gpr[22] = ULONG_MAX,
782				}
783			},
784			{
785				.descr = "RA = ULONG_MAX, RB = 0x1",
786				.instr = ppc_inst(PPC_RAW_ADD_DOT(20, 21, 22)),
787				.regs = {
788					.gpr[21] = ULONG_MAX,
789					.gpr[22] = 0x1,
790				}
791			},
792			{
793				.descr = "RA = INT_MIN, RB = INT_MIN",
794				.instr = ppc_inst(PPC_RAW_ADD_DOT(20, 21, 22)),
795				.regs = {
796					.gpr[21] = INT_MIN,
797					.gpr[22] = INT_MIN,
798				}
799			},
800			{
801				.descr = "RA = INT_MIN, RB = INT_MAX",
802				.instr = ppc_inst(PPC_RAW_ADD_DOT(20, 21, 22)),
803				.regs = {
804					.gpr[21] = INT_MIN,
805					.gpr[22] = INT_MAX,
806				}
807			},
808			{
809				.descr = "RA = INT_MAX, RB = INT_MAX",
810				.instr = ppc_inst(PPC_RAW_ADD_DOT(20, 21, 22)),
811				.regs = {
812					.gpr[21] = INT_MAX,
813					.gpr[22] = INT_MAX,
814				}
815			},
816			{
817				.descr = "RA = UINT_MAX, RB = UINT_MAX",
818				.instr = ppc_inst(PPC_RAW_ADD_DOT(20, 21, 22)),
819				.regs = {
820					.gpr[21] = UINT_MAX,
821					.gpr[22] = UINT_MAX,
822				}
823			},
824			{
825				.descr = "RA = UINT_MAX, RB = 0x1",
826				.instr = ppc_inst(PPC_RAW_ADD_DOT(20, 21, 22)),
827				.regs = {
828					.gpr[21] = UINT_MAX,
829					.gpr[22] = 0x1,
830				}
831			}
832		}
833	},
834	{
835		.mnemonic = "addc",
836		.subtests = {
837			{
838				.descr = "RA = LONG_MIN, RB = LONG_MIN",
839				.instr = ppc_inst(PPC_RAW_ADDC(20, 21, 22)),
840				.regs = {
841					.gpr[21] = LONG_MIN,
842					.gpr[22] = LONG_MIN,
843				}
844			},
845			{
846				.descr = "RA = LONG_MIN, RB = LONG_MAX",
847				.instr = ppc_inst(PPC_RAW_ADDC(20, 21, 22)),
848				.regs = {
849					.gpr[21] = LONG_MIN,
850					.gpr[22] = LONG_MAX,
851				}
852			},
853			{
854				.descr = "RA = LONG_MAX, RB = LONG_MAX",
855				.instr = ppc_inst(PPC_RAW_ADDC(20, 21, 22)),
856				.regs = {
857					.gpr[21] = LONG_MAX,
858					.gpr[22] = LONG_MAX,
859				}
860			},
861			{
862				.descr = "RA = ULONG_MAX, RB = ULONG_MAX",
863				.instr = ppc_inst(PPC_RAW_ADDC(20, 21, 22)),
864				.regs = {
865					.gpr[21] = ULONG_MAX,
866					.gpr[22] = ULONG_MAX,
867				}
868			},
869			{
870				.descr = "RA = ULONG_MAX, RB = 0x1",
871				.instr = ppc_inst(PPC_RAW_ADDC(20, 21, 22)),
872				.regs = {
873					.gpr[21] = ULONG_MAX,
874					.gpr[22] = 0x1,
875				}
876			},
877			{
878				.descr = "RA = INT_MIN, RB = INT_MIN",
879				.instr = ppc_inst(PPC_RAW_ADDC(20, 21, 22)),
880				.regs = {
881					.gpr[21] = INT_MIN,
882					.gpr[22] = INT_MIN,
883				}
884			},
885			{
886				.descr = "RA = INT_MIN, RB = INT_MAX",
887				.instr = ppc_inst(PPC_RAW_ADDC(20, 21, 22)),
888				.regs = {
889					.gpr[21] = INT_MIN,
890					.gpr[22] = INT_MAX,
891				}
892			},
893			{
894				.descr = "RA = INT_MAX, RB = INT_MAX",
895				.instr = ppc_inst(PPC_RAW_ADDC(20, 21, 22)),
896				.regs = {
897					.gpr[21] = INT_MAX,
898					.gpr[22] = INT_MAX,
899				}
900			},
901			{
902				.descr = "RA = UINT_MAX, RB = UINT_MAX",
903				.instr = ppc_inst(PPC_RAW_ADDC(20, 21, 22)),
904				.regs = {
905					.gpr[21] = UINT_MAX,
906					.gpr[22] = UINT_MAX,
907				}
908			},
909			{
910				.descr = "RA = UINT_MAX, RB = 0x1",
911				.instr = ppc_inst(PPC_RAW_ADDC(20, 21, 22)),
912				.regs = {
913					.gpr[21] = UINT_MAX,
914					.gpr[22] = 0x1,
915				}
916			},
917			{
918				.descr = "RA = LONG_MIN | INT_MIN, RB = LONG_MIN | INT_MIN",
919				.instr = ppc_inst(PPC_RAW_ADDC(20, 21, 22)),
920				.regs = {
921					.gpr[21] = LONG_MIN | (uint)INT_MIN,
922					.gpr[22] = LONG_MIN | (uint)INT_MIN,
923				}
924			}
925		}
926	},
927	{
928		.mnemonic = "addc.",
929		.subtests = {
930			{
931				.descr = "RA = LONG_MIN, RB = LONG_MIN",
932				.flags = IGNORE_CCR,
933				.instr = ppc_inst(PPC_RAW_ADDC_DOT(20, 21, 22)),
934				.regs = {
935					.gpr[21] = LONG_MIN,
936					.gpr[22] = LONG_MIN,
937				}
938			},
939			{
940				.descr = "RA = LONG_MIN, RB = LONG_MAX",
941				.instr = ppc_inst(PPC_RAW_ADDC_DOT(20, 21, 22)),
942				.regs = {
943					.gpr[21] = LONG_MIN,
944					.gpr[22] = LONG_MAX,
945				}
946			},
947			{
948				.descr = "RA = LONG_MAX, RB = LONG_MAX",
949				.flags = IGNORE_CCR,
950				.instr = ppc_inst(PPC_RAW_ADDC_DOT(20, 21, 22)),
951				.regs = {
952					.gpr[21] = LONG_MAX,
953					.gpr[22] = LONG_MAX,
954				}
955			},
956			{
957				.descr = "RA = ULONG_MAX, RB = ULONG_MAX",
958				.instr = ppc_inst(PPC_RAW_ADDC_DOT(20, 21, 22)),
959				.regs = {
960					.gpr[21] = ULONG_MAX,
961					.gpr[22] = ULONG_MAX,
962				}
963			},
964			{
965				.descr = "RA = ULONG_MAX, RB = 0x1",
966				.instr = ppc_inst(PPC_RAW_ADDC_DOT(20, 21, 22)),
967				.regs = {
968					.gpr[21] = ULONG_MAX,
969					.gpr[22] = 0x1,
970				}
971			},
972			{
973				.descr = "RA = INT_MIN, RB = INT_MIN",
974				.instr = ppc_inst(PPC_RAW_ADDC_DOT(20, 21, 22)),
975				.regs = {
976					.gpr[21] = INT_MIN,
977					.gpr[22] = INT_MIN,
978				}
979			},
980			{
981				.descr = "RA = INT_MIN, RB = INT_MAX",
982				.instr = ppc_inst(PPC_RAW_ADDC_DOT(20, 21, 22)),
983				.regs = {
984					.gpr[21] = INT_MIN,
985					.gpr[22] = INT_MAX,
986				}
987			},
988			{
989				.descr = "RA = INT_MAX, RB = INT_MAX",
990				.instr = ppc_inst(PPC_RAW_ADDC_DOT(20, 21, 22)),
991				.regs = {
992					.gpr[21] = INT_MAX,
993					.gpr[22] = INT_MAX,
994				}
995			},
996			{
997				.descr = "RA = UINT_MAX, RB = UINT_MAX",
998				.instr = ppc_inst(PPC_RAW_ADDC_DOT(20, 21, 22)),
999				.regs = {
1000					.gpr[21] = UINT_MAX,
1001					.gpr[22] = UINT_MAX,
1002				}
1003			},
1004			{
1005				.descr = "RA = UINT_MAX, RB = 0x1",
1006				.instr = ppc_inst(PPC_RAW_ADDC_DOT(20, 21, 22)),
1007				.regs = {
1008					.gpr[21] = UINT_MAX,
1009					.gpr[22] = 0x1,
1010				}
1011			},
1012			{
1013				.descr = "RA = LONG_MIN | INT_MIN, RB = LONG_MIN | INT_MIN",
1014				.instr = ppc_inst(PPC_RAW_ADDC_DOT(20, 21, 22)),
1015				.regs = {
1016					.gpr[21] = LONG_MIN | (uint)INT_MIN,
1017					.gpr[22] = LONG_MIN | (uint)INT_MIN,
1018				}
1019			}
1020		}
1021	},
1022	{
1023		.mnemonic = "divde",
1024		.subtests = {
1025			{
1026				.descr = "RA = LONG_MIN, RB = LONG_MIN",
1027				.instr = ppc_inst(PPC_RAW_DIVDE(20, 21, 22)),
1028				.regs = {
1029					.gpr[21] = LONG_MIN,
1030					.gpr[22] = LONG_MIN,
1031				}
1032			},
1033			{
1034				.descr = "RA = 1L, RB = 0",
1035				.instr = ppc_inst(PPC_RAW_DIVDE(20, 21, 22)),
1036				.flags = IGNORE_GPR(20),
1037				.regs = {
1038					.gpr[21] = 1L,
1039					.gpr[22] = 0,
1040				}
1041			},
1042			{
1043				.descr = "RA = LONG_MIN, RB = LONG_MAX",
1044				.instr = ppc_inst(PPC_RAW_DIVDE(20, 21, 22)),
1045				.regs = {
1046					.gpr[21] = LONG_MIN,
1047					.gpr[22] = LONG_MAX,
1048				}
1049			}
1050		}
1051	},
1052	{
1053		.mnemonic = "divde.",
1054		.subtests = {
1055			{
1056				.descr = "RA = LONG_MIN, RB = LONG_MIN",
1057				.instr = ppc_inst(PPC_RAW_DIVDE_DOT(20, 21, 22)),
1058				.regs = {
1059					.gpr[21] = LONG_MIN,
1060					.gpr[22] = LONG_MIN,
1061				}
1062			},
1063			{
1064				.descr = "RA = 1L, RB = 0",
1065				.instr = ppc_inst(PPC_RAW_DIVDE_DOT(20, 21, 22)),
1066				.flags = IGNORE_GPR(20),
1067				.regs = {
1068					.gpr[21] = 1L,
1069					.gpr[22] = 0,
1070				}
1071			},
1072			{
1073				.descr = "RA = LONG_MIN, RB = LONG_MAX",
1074				.instr = ppc_inst(PPC_RAW_DIVDE_DOT(20, 21, 22)),
1075				.regs = {
1076					.gpr[21] = LONG_MIN,
1077					.gpr[22] = LONG_MAX,
1078				}
1079			}
1080		}
1081	},
1082	{
1083		.mnemonic = "divdeu",
1084		.subtests = {
1085			{
1086				.descr = "RA = LONG_MIN, RB = LONG_MIN",
1087				.instr = ppc_inst(PPC_RAW_DIVDEU(20, 21, 22)),
1088				.flags = IGNORE_GPR(20),
1089				.regs = {
1090					.gpr[21] = LONG_MIN,
1091					.gpr[22] = LONG_MIN,
1092				}
1093			},
1094			{
1095				.descr = "RA = 1L, RB = 0",
1096				.instr = ppc_inst(PPC_RAW_DIVDEU(20, 21, 22)),
1097				.flags = IGNORE_GPR(20),
1098				.regs = {
1099					.gpr[21] = 1L,
1100					.gpr[22] = 0,
1101				}
1102			},
1103			{
1104				.descr = "RA = LONG_MIN, RB = LONG_MAX",
1105				.instr = ppc_inst(PPC_RAW_DIVDEU(20, 21, 22)),
1106				.regs = {
1107					.gpr[21] = LONG_MIN,
1108					.gpr[22] = LONG_MAX,
1109				}
1110			},
1111			{
1112				.descr = "RA = LONG_MAX - 1, RB = LONG_MAX",
1113				.instr = ppc_inst(PPC_RAW_DIVDEU(20, 21, 22)),
1114				.regs = {
1115					.gpr[21] = LONG_MAX - 1,
1116					.gpr[22] = LONG_MAX,
1117				}
1118			},
1119			{
1120				.descr = "RA = LONG_MIN + 1, RB = LONG_MIN",
1121				.instr = ppc_inst(PPC_RAW_DIVDEU(20, 21, 22)),
1122				.flags = IGNORE_GPR(20),
1123				.regs = {
1124					.gpr[21] = LONG_MIN + 1,
1125					.gpr[22] = LONG_MIN,
1126				}
1127			}
1128		}
1129	},
1130	{
1131		.mnemonic = "divdeu.",
1132		.subtests = {
1133			{
1134				.descr = "RA = LONG_MIN, RB = LONG_MIN",
1135				.instr = ppc_inst(PPC_RAW_DIVDEU_DOT(20, 21, 22)),
1136				.flags = IGNORE_GPR(20),
1137				.regs = {
1138					.gpr[21] = LONG_MIN,
1139					.gpr[22] = LONG_MIN,
1140				}
1141			},
1142			{
1143				.descr = "RA = 1L, RB = 0",
1144				.instr = ppc_inst(PPC_RAW_DIVDEU_DOT(20, 21, 22)),
1145				.flags = IGNORE_GPR(20),
1146				.regs = {
1147					.gpr[21] = 1L,
1148					.gpr[22] = 0,
1149				}
1150			},
1151			{
1152				.descr = "RA = LONG_MIN, RB = LONG_MAX",
1153				.instr = ppc_inst(PPC_RAW_DIVDEU_DOT(20, 21, 22)),
1154				.regs = {
1155					.gpr[21] = LONG_MIN,
1156					.gpr[22] = LONG_MAX,
1157				}
1158			},
1159			{
1160				.descr = "RA = LONG_MAX - 1, RB = LONG_MAX",
1161				.instr = ppc_inst(PPC_RAW_DIVDEU_DOT(20, 21, 22)),
1162				.regs = {
1163					.gpr[21] = LONG_MAX - 1,
1164					.gpr[22] = LONG_MAX,
1165				}
1166			},
1167			{
1168				.descr = "RA = LONG_MIN + 1, RB = LONG_MIN",
1169				.instr = ppc_inst(PPC_RAW_DIVDEU_DOT(20, 21, 22)),
1170				.flags = IGNORE_GPR(20),
1171				.regs = {
1172					.gpr[21] = LONG_MIN + 1,
1173					.gpr[22] = LONG_MIN,
1174				}
1175			}
1176		}
1177	},
1178	{
1179		.mnemonic = "paddi",
1180		.cpu_feature = CPU_FTR_ARCH_31,
1181		.subtests = {
1182			{
1183				.descr = "RA = LONG_MIN, SI = SI_MIN, R = 0",
1184				.instr = TEST_PADDI(21, 22, SI_MIN, 0),
1185				.regs = {
1186					.gpr[21] = 0,
1187					.gpr[22] = LONG_MIN,
1188				}
1189			},
1190			{
1191				.descr = "RA = LONG_MIN, SI = SI_MAX, R = 0",
1192				.instr = TEST_PADDI(21, 22, SI_MAX, 0),
1193				.regs = {
1194					.gpr[21] = 0,
1195					.gpr[22] = LONG_MIN,
1196				}
1197			},
1198			{
1199				.descr = "RA = LONG_MAX, SI = SI_MAX, R = 0",
1200				.instr = TEST_PADDI(21, 22, SI_MAX, 0),
1201				.regs = {
1202					.gpr[21] = 0,
1203					.gpr[22] = LONG_MAX,
1204				}
1205			},
1206			{
1207				.descr = "RA = ULONG_MAX, SI = SI_UMAX, R = 0",
1208				.instr = TEST_PADDI(21, 22, SI_UMAX, 0),
1209				.regs = {
1210					.gpr[21] = 0,
1211					.gpr[22] = ULONG_MAX,
1212				}
1213			},
1214			{
1215				.descr = "RA = ULONG_MAX, SI = 0x1, R = 0",
1216				.instr = TEST_PADDI(21, 22, 0x1, 0),
1217				.regs = {
1218					.gpr[21] = 0,
1219					.gpr[22] = ULONG_MAX,
1220				}
1221			},
1222			{
1223				.descr = "RA = INT_MIN, SI = SI_MIN, R = 0",
1224				.instr = TEST_PADDI(21, 22, SI_MIN, 0),
1225				.regs = {
1226					.gpr[21] = 0,
1227					.gpr[22] = INT_MIN,
1228				}
1229			},
1230			{
1231				.descr = "RA = INT_MIN, SI = SI_MAX, R = 0",
1232				.instr = TEST_PADDI(21, 22, SI_MAX, 0),
1233				.regs = {
1234					.gpr[21] = 0,
1235					.gpr[22] = INT_MIN,
1236				}
1237			},
1238			{
1239				.descr = "RA = INT_MAX, SI = SI_MAX, R = 0",
1240				.instr = TEST_PADDI(21, 22, SI_MAX, 0),
1241				.regs = {
1242					.gpr[21] = 0,
1243					.gpr[22] = INT_MAX,
1244				}
1245			},
1246			{
1247				.descr = "RA = UINT_MAX, SI = 0x1, R = 0",
1248				.instr = TEST_PADDI(21, 22, 0x1, 0),
1249				.regs = {
1250					.gpr[21] = 0,
1251					.gpr[22] = UINT_MAX,
1252				}
1253			},
1254			{
1255				.descr = "RA = UINT_MAX, SI = SI_MAX, R = 0",
1256				.instr = TEST_PADDI(21, 22, SI_MAX, 0),
1257				.regs = {
1258					.gpr[21] = 0,
1259					.gpr[22] = UINT_MAX,
1260				}
1261			},
1262			{
1263				.descr = "RA is r0, SI = SI_MIN, R = 0",
1264				.instr = TEST_PADDI(21, 0, SI_MIN, 0),
1265				.regs = {
1266					.gpr[21] = 0x0,
1267				}
1268			},
1269			{
1270				.descr = "RA = 0, SI = SI_MIN, R = 0",
1271				.instr = TEST_PADDI(21, 22, SI_MIN, 0),
1272				.regs = {
1273					.gpr[21] = 0x0,
1274					.gpr[22] = 0x0,
1275				}
1276			},
1277			{
1278				.descr = "RA is r0, SI = 0, R = 1",
1279				.instr = TEST_PADDI(21, 0, 0, 1),
1280				.regs = {
1281					.gpr[21] = 0,
1282				}
1283			},
1284			{
1285				.descr = "RA is r0, SI = SI_MIN, R = 1",
1286				.instr = TEST_PADDI(21, 0, SI_MIN, 1),
1287				.regs = {
1288					.gpr[21] = 0,
1289				}
1290			},
1291			/* Invalid instruction form with R = 1 and RA != 0 */
1292			{
1293				.descr = "RA = R22(0), SI = 0, R = 1",
1294				.instr = TEST_PADDI(21, 22, 0, 1),
1295				.flags = NEGATIVE_TEST,
1296				.regs = {
1297					.gpr[21] = 0,
1298					.gpr[22] = 0,
1299				}
1300			}
1301		}
1302	}
1303};
1304
1305static int __init emulate_compute_instr(struct pt_regs *regs,
1306					struct ppc_inst instr,
1307					bool negative)
1308{
1309	int analysed;
1310	struct instruction_op op;
1311
1312	if (!regs || !ppc_inst_val(instr))
1313		return -EINVAL;
1314
1315	regs->nip = patch_site_addr(&patch__exec_instr);
1316
1317	analysed = analyse_instr(&op, regs, instr);
1318	if (analysed != 1 || GETTYPE(op.type) != COMPUTE) {
1319		if (negative)
1320			return -EFAULT;
1321		pr_info("emulation failed, instruction = %s\n", ppc_inst_as_str(instr));
1322		return -EFAULT;
1323	}
1324	if (analysed == 1 && negative)
1325		pr_info("negative test failed, instruction = %s\n", ppc_inst_as_str(instr));
1326	if (!negative)
1327		emulate_update_regs(regs, &op);
1328	return 0;
1329}
1330
1331static int __init execute_compute_instr(struct pt_regs *regs,
1332					struct ppc_inst instr)
1333{
1334	extern int exec_instr(struct pt_regs *regs);
1335
1336	if (!regs || !ppc_inst_val(instr))
1337		return -EINVAL;
1338
1339	/* Patch the NOP with the actual instruction */
1340	patch_instruction_site(&patch__exec_instr, instr);
1341	if (exec_instr(regs)) {
1342		pr_info("execution failed, instruction = %s\n", ppc_inst_as_str(instr));
1343		return -EFAULT;
1344	}
1345
1346	return 0;
1347}
1348
1349#define gpr_mismatch(gprn, exp, got)	\
1350	pr_info("GPR%u mismatch, exp = 0x%016lx, got = 0x%016lx\n",	\
1351		gprn, exp, got)
1352
1353#define reg_mismatch(name, exp, got)	\
1354	pr_info("%s mismatch, exp = 0x%016lx, got = 0x%016lx\n",	\
1355		name, exp, got)
1356
1357static void __init run_tests_compute(void)
1358{
1359	unsigned long flags;
1360	struct compute_test *test;
1361	struct pt_regs *regs, exp, got;
1362	unsigned int i, j, k;
1363	struct ppc_inst instr;
1364	bool ignore_gpr, ignore_xer, ignore_ccr, passed, rc, negative;
1365
1366	for (i = 0; i < ARRAY_SIZE(compute_tests); i++) {
1367		test = &compute_tests[i];
1368
1369		if (test->cpu_feature && !early_cpu_has_feature(test->cpu_feature)) {
1370			show_result(test->mnemonic, "SKIP (!CPU_FTR)");
1371			continue;
1372		}
1373
1374		for (j = 0; j < MAX_SUBTESTS && test->subtests[j].descr; j++) {
1375			instr = test->subtests[j].instr;
1376			flags = test->subtests[j].flags;
1377			regs = &test->subtests[j].regs;
1378			negative = flags & NEGATIVE_TEST;
1379			ignore_xer = flags & IGNORE_XER;
1380			ignore_ccr = flags & IGNORE_CCR;
1381			passed = true;
1382
1383			memcpy(&exp, regs, sizeof(struct pt_regs));
1384			memcpy(&got, regs, sizeof(struct pt_regs));
1385
1386			/*
1387			 * Set a compatible MSR value explicitly to ensure
1388			 * that XER and CR bits are updated appropriately
1389			 */
1390			exp.msr = MSR_KERNEL;
1391			got.msr = MSR_KERNEL;
1392
1393			rc = emulate_compute_instr(&got, instr, negative) != 0;
1394			if (negative) {
1395				/* skip executing instruction */
1396				passed = rc;
1397				goto print;
1398			} else if (rc || execute_compute_instr(&exp, instr)) {
1399				passed = false;
1400				goto print;
1401			}
1402
1403			/* Verify GPR values */
1404			for (k = 0; k < 32; k++) {
1405				ignore_gpr = flags & IGNORE_GPR(k);
1406				if (!ignore_gpr && exp.gpr[k] != got.gpr[k]) {
1407					passed = false;
1408					gpr_mismatch(k, exp.gpr[k], got.gpr[k]);
1409				}
1410			}
1411
1412			/* Verify LR value */
1413			if (exp.link != got.link) {
1414				passed = false;
1415				reg_mismatch("LR", exp.link, got.link);
1416			}
1417
1418			/* Verify XER value */
1419			if (!ignore_xer && exp.xer != got.xer) {
1420				passed = false;
1421				reg_mismatch("XER", exp.xer, got.xer);
1422			}
1423
1424			/* Verify CR value */
1425			if (!ignore_ccr && exp.ccr != got.ccr) {
1426				passed = false;
1427				reg_mismatch("CR", exp.ccr, got.ccr);
1428			}
1429
1430print:
1431			show_result_with_descr(test->mnemonic,
1432					       test->subtests[j].descr,
1433					       passed ? "PASS" : "FAIL");
1434		}
1435	}
1436}
1437
1438static int __init test_emulate_step(void)
1439{
1440	printk(KERN_INFO "Running instruction emulation self-tests ...\n");
1441	run_tests_load_store();
1442	run_tests_compute();
1443
1444	return 0;
1445}
1446late_initcall(test_emulate_step);
1447