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