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 
57 static 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 
79 static void __init show_result(char *mnemonic, char *result)
80 {
81 	pr_info("%-14s : %s\n", mnemonic, result);
82 }
83 
84 static 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 
90 static 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 
108 static 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 
131 static 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 
149 static 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 
173 static 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 
192 static 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 
210 static 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 
233 static 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
287 static 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 
330 static 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 
377 static 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 
420 static 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
467 static 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 
473 static 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 
479 static 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 
485 static 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
493 static 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
542 static 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
550 static 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
608 static 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 
615 #ifdef CONFIG_VSX
616 static void __init test_lxvp_stxvp(void)
617 {
618 	struct pt_regs regs;
619 	union {
620 		vector128 a;
621 		u32 b[4];
622 	} c[2];
623 	u32 cached_b[8];
624 	int stepped = -1;
625 
626 	if (!cpu_has_feature(CPU_FTR_ARCH_31)) {
627 		show_result("lxvp", "SKIP (!CPU_FTR_ARCH_31)");
628 		show_result("stxvp", "SKIP (!CPU_FTR_ARCH_31)");
629 		return;
630 	}
631 
632 	init_pt_regs(&regs);
633 
634 	/*** lxvp ***/
635 
636 	cached_b[0] = c[0].b[0] = 18233;
637 	cached_b[1] = c[0].b[1] = 34863571;
638 	cached_b[2] = c[0].b[2] = 834;
639 	cached_b[3] = c[0].b[3] = 6138911;
640 	cached_b[4] = c[1].b[0] = 1234;
641 	cached_b[5] = c[1].b[1] = 5678;
642 	cached_b[6] = c[1].b[2] = 91011;
643 	cached_b[7] = c[1].b[3] = 121314;
644 
645 	regs.gpr[4] = (unsigned long)&c[0].a;
646 
647 	/*
648 	 * lxvp XTp,DQ(RA)
649 	 * XTp = 32xTX + 2xTp
650 	 * let TX=1 Tp=1 RA=4 DQ=0
651 	 */
652 	stepped = emulate_step(&regs, ppc_inst(PPC_RAW_LXVP(34, 4, 0)));
653 
654 	if (stepped == 1 && cpu_has_feature(CPU_FTR_VSX)) {
655 		show_result("lxvp", "PASS");
656 	} else {
657 		if (!cpu_has_feature(CPU_FTR_VSX))
658 			show_result("lxvp", "PASS (!CPU_FTR_VSX)");
659 		else
660 			show_result("lxvp", "FAIL");
661 	}
662 
663 	/*** stxvp ***/
664 
665 	c[0].b[0] = 21379463;
666 	c[0].b[1] = 87;
667 	c[0].b[2] = 374234;
668 	c[0].b[3] = 4;
669 	c[1].b[0] = 90;
670 	c[1].b[1] = 122;
671 	c[1].b[2] = 555;
672 	c[1].b[3] = 32144;
673 
674 	/*
675 	 * stxvp XSp,DQ(RA)
676 	 * XSp = 32xSX + 2xSp
677 	 * let SX=1 Sp=1 RA=4 DQ=0
678 	 */
679 	stepped = emulate_step(&regs, ppc_inst(PPC_RAW_STXVP(34, 4, 0)));
680 
681 	if (stepped == 1 && cached_b[0] == c[0].b[0] && cached_b[1] == c[0].b[1] &&
682 	    cached_b[2] == c[0].b[2] && cached_b[3] == c[0].b[3] &&
683 	    cached_b[4] == c[1].b[0] && cached_b[5] == c[1].b[1] &&
684 	    cached_b[6] == c[1].b[2] && cached_b[7] == c[1].b[3] &&
685 	    cpu_has_feature(CPU_FTR_VSX)) {
686 		show_result("stxvp", "PASS");
687 	} else {
688 		if (!cpu_has_feature(CPU_FTR_VSX))
689 			show_result("stxvp", "PASS (!CPU_FTR_VSX)");
690 		else
691 			show_result("stxvp", "FAIL");
692 	}
693 }
694 #else
695 static void __init test_lxvp_stxvp(void)
696 {
697 	show_result("lxvp", "SKIP (CONFIG_VSX is not set)");
698 	show_result("stxvp", "SKIP (CONFIG_VSX is not set)");
699 }
700 #endif /* CONFIG_VSX */
701 
702 #ifdef CONFIG_VSX
703 static void __init test_lxvpx_stxvpx(void)
704 {
705 	struct pt_regs regs;
706 	union {
707 		vector128 a;
708 		u32 b[4];
709 	} c[2];
710 	u32 cached_b[8];
711 	int stepped = -1;
712 
713 	if (!cpu_has_feature(CPU_FTR_ARCH_31)) {
714 		show_result("lxvpx", "SKIP (!CPU_FTR_ARCH_31)");
715 		show_result("stxvpx", "SKIP (!CPU_FTR_ARCH_31)");
716 		return;
717 	}
718 
719 	init_pt_regs(&regs);
720 
721 	/*** lxvpx ***/
722 
723 	cached_b[0] = c[0].b[0] = 18233;
724 	cached_b[1] = c[0].b[1] = 34863571;
725 	cached_b[2] = c[0].b[2] = 834;
726 	cached_b[3] = c[0].b[3] = 6138911;
727 	cached_b[4] = c[1].b[0] = 1234;
728 	cached_b[5] = c[1].b[1] = 5678;
729 	cached_b[6] = c[1].b[2] = 91011;
730 	cached_b[7] = c[1].b[3] = 121314;
731 
732 	regs.gpr[3] = (unsigned long)&c[0].a;
733 	regs.gpr[4] = 0;
734 
735 	/*
736 	 * lxvpx XTp,RA,RB
737 	 * XTp = 32xTX + 2xTp
738 	 * let TX=1 Tp=1 RA=3 RB=4
739 	 */
740 	stepped = emulate_step(&regs, ppc_inst(PPC_RAW_LXVPX(34, 3, 4)));
741 
742 	if (stepped == 1 && cpu_has_feature(CPU_FTR_VSX)) {
743 		show_result("lxvpx", "PASS");
744 	} else {
745 		if (!cpu_has_feature(CPU_FTR_VSX))
746 			show_result("lxvpx", "PASS (!CPU_FTR_VSX)");
747 		else
748 			show_result("lxvpx", "FAIL");
749 	}
750 
751 	/*** stxvpx ***/
752 
753 	c[0].b[0] = 21379463;
754 	c[0].b[1] = 87;
755 	c[0].b[2] = 374234;
756 	c[0].b[3] = 4;
757 	c[1].b[0] = 90;
758 	c[1].b[1] = 122;
759 	c[1].b[2] = 555;
760 	c[1].b[3] = 32144;
761 
762 	/*
763 	 * stxvpx XSp,RA,RB
764 	 * XSp = 32xSX + 2xSp
765 	 * let SX=1 Sp=1 RA=3 RB=4
766 	 */
767 	stepped = emulate_step(&regs, ppc_inst(PPC_RAW_STXVPX(34, 3, 4)));
768 
769 	if (stepped == 1 && cached_b[0] == c[0].b[0] && cached_b[1] == c[0].b[1] &&
770 	    cached_b[2] == c[0].b[2] && cached_b[3] == c[0].b[3] &&
771 	    cached_b[4] == c[1].b[0] && cached_b[5] == c[1].b[1] &&
772 	    cached_b[6] == c[1].b[2] && cached_b[7] == c[1].b[3] &&
773 	    cpu_has_feature(CPU_FTR_VSX)) {
774 		show_result("stxvpx", "PASS");
775 	} else {
776 		if (!cpu_has_feature(CPU_FTR_VSX))
777 			show_result("stxvpx", "PASS (!CPU_FTR_VSX)");
778 		else
779 			show_result("stxvpx", "FAIL");
780 	}
781 }
782 #else
783 static void __init test_lxvpx_stxvpx(void)
784 {
785 	show_result("lxvpx", "SKIP (CONFIG_VSX is not set)");
786 	show_result("stxvpx", "SKIP (CONFIG_VSX is not set)");
787 }
788 #endif /* CONFIG_VSX */
789 
790 #ifdef CONFIG_VSX
791 static void __init test_plxvp_pstxvp(void)
792 {
793 	struct ppc_inst instr;
794 	struct pt_regs regs;
795 	union {
796 		vector128 a;
797 		u32 b[4];
798 	} c[2];
799 	u32 cached_b[8];
800 	int stepped = -1;
801 
802 	if (!cpu_has_feature(CPU_FTR_ARCH_31)) {
803 		show_result("plxvp", "SKIP (!CPU_FTR_ARCH_31)");
804 		show_result("pstxvp", "SKIP (!CPU_FTR_ARCH_31)");
805 		return;
806 	}
807 
808 	/*** plxvp ***/
809 
810 	cached_b[0] = c[0].b[0] = 18233;
811 	cached_b[1] = c[0].b[1] = 34863571;
812 	cached_b[2] = c[0].b[2] = 834;
813 	cached_b[3] = c[0].b[3] = 6138911;
814 	cached_b[4] = c[1].b[0] = 1234;
815 	cached_b[5] = c[1].b[1] = 5678;
816 	cached_b[6] = c[1].b[2] = 91011;
817 	cached_b[7] = c[1].b[3] = 121314;
818 
819 	init_pt_regs(&regs);
820 	regs.gpr[3] = (unsigned long)&c[0].a;
821 
822 	/*
823 	 * plxvp XTp,D(RA),R
824 	 * XTp = 32xTX + 2xTp
825 	 * let RA=3 R=0 D=d0||d1=0 R=0 Tp=1 TX=1
826 	 */
827 	instr = ppc_inst_prefix(PPC_RAW_PLXVP(34, 0, 3, 0) >> 32,
828 			PPC_RAW_PLXVP(34, 0, 3, 0) & 0xffffffff);
829 
830 	stepped = emulate_step(&regs, instr);
831 	if (stepped == 1 && cpu_has_feature(CPU_FTR_VSX)) {
832 		show_result("plxvp", "PASS");
833 	} else {
834 		if (!cpu_has_feature(CPU_FTR_VSX))
835 			show_result("plxvp", "PASS (!CPU_FTR_VSX)");
836 		else
837 			show_result("plxvp", "FAIL");
838 	}
839 
840 	/*** pstxvp ***/
841 
842 	c[0].b[0] = 21379463;
843 	c[0].b[1] = 87;
844 	c[0].b[2] = 374234;
845 	c[0].b[3] = 4;
846 	c[1].b[0] = 90;
847 	c[1].b[1] = 122;
848 	c[1].b[2] = 555;
849 	c[1].b[3] = 32144;
850 
851 	/*
852 	 * pstxvp XSp,D(RA),R
853 	 * XSp = 32xSX + 2xSp
854 	 * let RA=3 D=d0||d1=0 R=0 Sp=1 SX=1
855 	 */
856 	instr = ppc_inst_prefix(PPC_RAW_PSTXVP(34, 0, 3, 0) >> 32,
857 			PPC_RAW_PSTXVP(34, 0, 3, 0) & 0xffffffff);
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 		struct ppc_inst 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_INST_NOP),
926 				.regs = {
927 					.gpr[0] = LONG_MAX,
928 				}
929 			}
930 		}
931 	},
932 	{
933 		.mnemonic = "add",
934 		.subtests = {
935 			{
936 				.descr = "RA = LONG_MIN, RB = LONG_MIN",
937 				.instr = ppc_inst(PPC_RAW_ADD(20, 21, 22)),
938 				.regs = {
939 					.gpr[21] = LONG_MIN,
940 					.gpr[22] = LONG_MIN,
941 				}
942 			},
943 			{
944 				.descr = "RA = LONG_MIN, RB = LONG_MAX",
945 				.instr = ppc_inst(PPC_RAW_ADD(20, 21, 22)),
946 				.regs = {
947 					.gpr[21] = LONG_MIN,
948 					.gpr[22] = LONG_MAX,
949 				}
950 			},
951 			{
952 				.descr = "RA = LONG_MAX, RB = LONG_MAX",
953 				.instr = ppc_inst(PPC_RAW_ADD(20, 21, 22)),
954 				.regs = {
955 					.gpr[21] = LONG_MAX,
956 					.gpr[22] = LONG_MAX,
957 				}
958 			},
959 			{
960 				.descr = "RA = ULONG_MAX, RB = ULONG_MAX",
961 				.instr = ppc_inst(PPC_RAW_ADD(20, 21, 22)),
962 				.regs = {
963 					.gpr[21] = ULONG_MAX,
964 					.gpr[22] = ULONG_MAX,
965 				}
966 			},
967 			{
968 				.descr = "RA = ULONG_MAX, RB = 0x1",
969 				.instr = ppc_inst(PPC_RAW_ADD(20, 21, 22)),
970 				.regs = {
971 					.gpr[21] = ULONG_MAX,
972 					.gpr[22] = 0x1,
973 				}
974 			},
975 			{
976 				.descr = "RA = INT_MIN, RB = INT_MIN",
977 				.instr = ppc_inst(PPC_RAW_ADD(20, 21, 22)),
978 				.regs = {
979 					.gpr[21] = INT_MIN,
980 					.gpr[22] = INT_MIN,
981 				}
982 			},
983 			{
984 				.descr = "RA = INT_MIN, RB = INT_MAX",
985 				.instr = ppc_inst(PPC_RAW_ADD(20, 21, 22)),
986 				.regs = {
987 					.gpr[21] = INT_MIN,
988 					.gpr[22] = INT_MAX,
989 				}
990 			},
991 			{
992 				.descr = "RA = INT_MAX, RB = INT_MAX",
993 				.instr = ppc_inst(PPC_RAW_ADD(20, 21, 22)),
994 				.regs = {
995 					.gpr[21] = INT_MAX,
996 					.gpr[22] = INT_MAX,
997 				}
998 			},
999 			{
1000 				.descr = "RA = UINT_MAX, RB = UINT_MAX",
1001 				.instr = ppc_inst(PPC_RAW_ADD(20, 21, 22)),
1002 				.regs = {
1003 					.gpr[21] = UINT_MAX,
1004 					.gpr[22] = UINT_MAX,
1005 				}
1006 			},
1007 			{
1008 				.descr = "RA = UINT_MAX, RB = 0x1",
1009 				.instr = ppc_inst(PPC_RAW_ADD(20, 21, 22)),
1010 				.regs = {
1011 					.gpr[21] = UINT_MAX,
1012 					.gpr[22] = 0x1,
1013 				}
1014 			}
1015 		}
1016 	},
1017 	{
1018 		.mnemonic = "add.",
1019 		.subtests = {
1020 			{
1021 				.descr = "RA = LONG_MIN, RB = LONG_MIN",
1022 				.flags = IGNORE_CCR,
1023 				.instr = ppc_inst(PPC_RAW_ADD_DOT(20, 21, 22)),
1024 				.regs = {
1025 					.gpr[21] = LONG_MIN,
1026 					.gpr[22] = LONG_MIN,
1027 				}
1028 			},
1029 			{
1030 				.descr = "RA = LONG_MIN, RB = LONG_MAX",
1031 				.instr = ppc_inst(PPC_RAW_ADD_DOT(20, 21, 22)),
1032 				.regs = {
1033 					.gpr[21] = LONG_MIN,
1034 					.gpr[22] = LONG_MAX,
1035 				}
1036 			},
1037 			{
1038 				.descr = "RA = LONG_MAX, RB = LONG_MAX",
1039 				.flags = IGNORE_CCR,
1040 				.instr = ppc_inst(PPC_RAW_ADD_DOT(20, 21, 22)),
1041 				.regs = {
1042 					.gpr[21] = LONG_MAX,
1043 					.gpr[22] = LONG_MAX,
1044 				}
1045 			},
1046 			{
1047 				.descr = "RA = ULONG_MAX, RB = ULONG_MAX",
1048 				.instr = ppc_inst(PPC_RAW_ADD_DOT(20, 21, 22)),
1049 				.regs = {
1050 					.gpr[21] = ULONG_MAX,
1051 					.gpr[22] = ULONG_MAX,
1052 				}
1053 			},
1054 			{
1055 				.descr = "RA = ULONG_MAX, RB = 0x1",
1056 				.instr = ppc_inst(PPC_RAW_ADD_DOT(20, 21, 22)),
1057 				.regs = {
1058 					.gpr[21] = ULONG_MAX,
1059 					.gpr[22] = 0x1,
1060 				}
1061 			},
1062 			{
1063 				.descr = "RA = INT_MIN, RB = INT_MIN",
1064 				.instr = ppc_inst(PPC_RAW_ADD_DOT(20, 21, 22)),
1065 				.regs = {
1066 					.gpr[21] = INT_MIN,
1067 					.gpr[22] = INT_MIN,
1068 				}
1069 			},
1070 			{
1071 				.descr = "RA = INT_MIN, RB = INT_MAX",
1072 				.instr = ppc_inst(PPC_RAW_ADD_DOT(20, 21, 22)),
1073 				.regs = {
1074 					.gpr[21] = INT_MIN,
1075 					.gpr[22] = INT_MAX,
1076 				}
1077 			},
1078 			{
1079 				.descr = "RA = INT_MAX, RB = INT_MAX",
1080 				.instr = ppc_inst(PPC_RAW_ADD_DOT(20, 21, 22)),
1081 				.regs = {
1082 					.gpr[21] = INT_MAX,
1083 					.gpr[22] = INT_MAX,
1084 				}
1085 			},
1086 			{
1087 				.descr = "RA = UINT_MAX, RB = UINT_MAX",
1088 				.instr = ppc_inst(PPC_RAW_ADD_DOT(20, 21, 22)),
1089 				.regs = {
1090 					.gpr[21] = UINT_MAX,
1091 					.gpr[22] = UINT_MAX,
1092 				}
1093 			},
1094 			{
1095 				.descr = "RA = UINT_MAX, RB = 0x1",
1096 				.instr = ppc_inst(PPC_RAW_ADD_DOT(20, 21, 22)),
1097 				.regs = {
1098 					.gpr[21] = UINT_MAX,
1099 					.gpr[22] = 0x1,
1100 				}
1101 			}
1102 		}
1103 	},
1104 	{
1105 		.mnemonic = "addc",
1106 		.subtests = {
1107 			{
1108 				.descr = "RA = LONG_MIN, RB = LONG_MIN",
1109 				.instr = ppc_inst(PPC_RAW_ADDC(20, 21, 22)),
1110 				.regs = {
1111 					.gpr[21] = LONG_MIN,
1112 					.gpr[22] = LONG_MIN,
1113 				}
1114 			},
1115 			{
1116 				.descr = "RA = LONG_MIN, RB = LONG_MAX",
1117 				.instr = ppc_inst(PPC_RAW_ADDC(20, 21, 22)),
1118 				.regs = {
1119 					.gpr[21] = LONG_MIN,
1120 					.gpr[22] = LONG_MAX,
1121 				}
1122 			},
1123 			{
1124 				.descr = "RA = LONG_MAX, RB = LONG_MAX",
1125 				.instr = ppc_inst(PPC_RAW_ADDC(20, 21, 22)),
1126 				.regs = {
1127 					.gpr[21] = LONG_MAX,
1128 					.gpr[22] = LONG_MAX,
1129 				}
1130 			},
1131 			{
1132 				.descr = "RA = ULONG_MAX, RB = ULONG_MAX",
1133 				.instr = ppc_inst(PPC_RAW_ADDC(20, 21, 22)),
1134 				.regs = {
1135 					.gpr[21] = ULONG_MAX,
1136 					.gpr[22] = ULONG_MAX,
1137 				}
1138 			},
1139 			{
1140 				.descr = "RA = ULONG_MAX, RB = 0x1",
1141 				.instr = ppc_inst(PPC_RAW_ADDC(20, 21, 22)),
1142 				.regs = {
1143 					.gpr[21] = ULONG_MAX,
1144 					.gpr[22] = 0x1,
1145 				}
1146 			},
1147 			{
1148 				.descr = "RA = INT_MIN, RB = INT_MIN",
1149 				.instr = ppc_inst(PPC_RAW_ADDC(20, 21, 22)),
1150 				.regs = {
1151 					.gpr[21] = INT_MIN,
1152 					.gpr[22] = INT_MIN,
1153 				}
1154 			},
1155 			{
1156 				.descr = "RA = INT_MIN, RB = INT_MAX",
1157 				.instr = ppc_inst(PPC_RAW_ADDC(20, 21, 22)),
1158 				.regs = {
1159 					.gpr[21] = INT_MIN,
1160 					.gpr[22] = INT_MAX,
1161 				}
1162 			},
1163 			{
1164 				.descr = "RA = INT_MAX, RB = INT_MAX",
1165 				.instr = ppc_inst(PPC_RAW_ADDC(20, 21, 22)),
1166 				.regs = {
1167 					.gpr[21] = INT_MAX,
1168 					.gpr[22] = INT_MAX,
1169 				}
1170 			},
1171 			{
1172 				.descr = "RA = UINT_MAX, RB = UINT_MAX",
1173 				.instr = ppc_inst(PPC_RAW_ADDC(20, 21, 22)),
1174 				.regs = {
1175 					.gpr[21] = UINT_MAX,
1176 					.gpr[22] = UINT_MAX,
1177 				}
1178 			},
1179 			{
1180 				.descr = "RA = UINT_MAX, RB = 0x1",
1181 				.instr = ppc_inst(PPC_RAW_ADDC(20, 21, 22)),
1182 				.regs = {
1183 					.gpr[21] = UINT_MAX,
1184 					.gpr[22] = 0x1,
1185 				}
1186 			},
1187 			{
1188 				.descr = "RA = LONG_MIN | INT_MIN, RB = LONG_MIN | INT_MIN",
1189 				.instr = ppc_inst(PPC_RAW_ADDC(20, 21, 22)),
1190 				.regs = {
1191 					.gpr[21] = LONG_MIN | (uint)INT_MIN,
1192 					.gpr[22] = LONG_MIN | (uint)INT_MIN,
1193 				}
1194 			}
1195 		}
1196 	},
1197 	{
1198 		.mnemonic = "addc.",
1199 		.subtests = {
1200 			{
1201 				.descr = "RA = LONG_MIN, RB = LONG_MIN",
1202 				.flags = IGNORE_CCR,
1203 				.instr = ppc_inst(PPC_RAW_ADDC_DOT(20, 21, 22)),
1204 				.regs = {
1205 					.gpr[21] = LONG_MIN,
1206 					.gpr[22] = LONG_MIN,
1207 				}
1208 			},
1209 			{
1210 				.descr = "RA = LONG_MIN, RB = LONG_MAX",
1211 				.instr = ppc_inst(PPC_RAW_ADDC_DOT(20, 21, 22)),
1212 				.regs = {
1213 					.gpr[21] = LONG_MIN,
1214 					.gpr[22] = LONG_MAX,
1215 				}
1216 			},
1217 			{
1218 				.descr = "RA = LONG_MAX, RB = LONG_MAX",
1219 				.flags = IGNORE_CCR,
1220 				.instr = ppc_inst(PPC_RAW_ADDC_DOT(20, 21, 22)),
1221 				.regs = {
1222 					.gpr[21] = LONG_MAX,
1223 					.gpr[22] = LONG_MAX,
1224 				}
1225 			},
1226 			{
1227 				.descr = "RA = ULONG_MAX, RB = ULONG_MAX",
1228 				.instr = ppc_inst(PPC_RAW_ADDC_DOT(20, 21, 22)),
1229 				.regs = {
1230 					.gpr[21] = ULONG_MAX,
1231 					.gpr[22] = ULONG_MAX,
1232 				}
1233 			},
1234 			{
1235 				.descr = "RA = ULONG_MAX, RB = 0x1",
1236 				.instr = ppc_inst(PPC_RAW_ADDC_DOT(20, 21, 22)),
1237 				.regs = {
1238 					.gpr[21] = ULONG_MAX,
1239 					.gpr[22] = 0x1,
1240 				}
1241 			},
1242 			{
1243 				.descr = "RA = INT_MIN, RB = INT_MIN",
1244 				.instr = ppc_inst(PPC_RAW_ADDC_DOT(20, 21, 22)),
1245 				.regs = {
1246 					.gpr[21] = INT_MIN,
1247 					.gpr[22] = INT_MIN,
1248 				}
1249 			},
1250 			{
1251 				.descr = "RA = INT_MIN, RB = INT_MAX",
1252 				.instr = ppc_inst(PPC_RAW_ADDC_DOT(20, 21, 22)),
1253 				.regs = {
1254 					.gpr[21] = INT_MIN,
1255 					.gpr[22] = INT_MAX,
1256 				}
1257 			},
1258 			{
1259 				.descr = "RA = INT_MAX, RB = INT_MAX",
1260 				.instr = ppc_inst(PPC_RAW_ADDC_DOT(20, 21, 22)),
1261 				.regs = {
1262 					.gpr[21] = INT_MAX,
1263 					.gpr[22] = INT_MAX,
1264 				}
1265 			},
1266 			{
1267 				.descr = "RA = UINT_MAX, RB = UINT_MAX",
1268 				.instr = ppc_inst(PPC_RAW_ADDC_DOT(20, 21, 22)),
1269 				.regs = {
1270 					.gpr[21] = UINT_MAX,
1271 					.gpr[22] = UINT_MAX,
1272 				}
1273 			},
1274 			{
1275 				.descr = "RA = UINT_MAX, RB = 0x1",
1276 				.instr = ppc_inst(PPC_RAW_ADDC_DOT(20, 21, 22)),
1277 				.regs = {
1278 					.gpr[21] = UINT_MAX,
1279 					.gpr[22] = 0x1,
1280 				}
1281 			},
1282 			{
1283 				.descr = "RA = LONG_MIN | INT_MIN, RB = LONG_MIN | INT_MIN",
1284 				.instr = ppc_inst(PPC_RAW_ADDC_DOT(20, 21, 22)),
1285 				.regs = {
1286 					.gpr[21] = LONG_MIN | (uint)INT_MIN,
1287 					.gpr[22] = LONG_MIN | (uint)INT_MIN,
1288 				}
1289 			}
1290 		}
1291 	},
1292 	{
1293 		.mnemonic = "divde",
1294 		.subtests = {
1295 			{
1296 				.descr = "RA = LONG_MIN, RB = LONG_MIN",
1297 				.instr = ppc_inst(PPC_RAW_DIVDE(20, 21, 22)),
1298 				.regs = {
1299 					.gpr[21] = LONG_MIN,
1300 					.gpr[22] = LONG_MIN,
1301 				}
1302 			},
1303 			{
1304 				.descr = "RA = 1L, RB = 0",
1305 				.instr = ppc_inst(PPC_RAW_DIVDE(20, 21, 22)),
1306 				.flags = IGNORE_GPR(20),
1307 				.regs = {
1308 					.gpr[21] = 1L,
1309 					.gpr[22] = 0,
1310 				}
1311 			},
1312 			{
1313 				.descr = "RA = LONG_MIN, RB = LONG_MAX",
1314 				.instr = ppc_inst(PPC_RAW_DIVDE(20, 21, 22)),
1315 				.regs = {
1316 					.gpr[21] = LONG_MIN,
1317 					.gpr[22] = LONG_MAX,
1318 				}
1319 			}
1320 		}
1321 	},
1322 	{
1323 		.mnemonic = "divde.",
1324 		.subtests = {
1325 			{
1326 				.descr = "RA = LONG_MIN, RB = LONG_MIN",
1327 				.instr = ppc_inst(PPC_RAW_DIVDE_DOT(20, 21, 22)),
1328 				.regs = {
1329 					.gpr[21] = LONG_MIN,
1330 					.gpr[22] = LONG_MIN,
1331 				}
1332 			},
1333 			{
1334 				.descr = "RA = 1L, RB = 0",
1335 				.instr = ppc_inst(PPC_RAW_DIVDE_DOT(20, 21, 22)),
1336 				.flags = IGNORE_GPR(20),
1337 				.regs = {
1338 					.gpr[21] = 1L,
1339 					.gpr[22] = 0,
1340 				}
1341 			},
1342 			{
1343 				.descr = "RA = LONG_MIN, RB = LONG_MAX",
1344 				.instr = ppc_inst(PPC_RAW_DIVDE_DOT(20, 21, 22)),
1345 				.regs = {
1346 					.gpr[21] = LONG_MIN,
1347 					.gpr[22] = LONG_MAX,
1348 				}
1349 			}
1350 		}
1351 	},
1352 	{
1353 		.mnemonic = "divdeu",
1354 		.subtests = {
1355 			{
1356 				.descr = "RA = LONG_MIN, RB = LONG_MIN",
1357 				.instr = ppc_inst(PPC_RAW_DIVDEU(20, 21, 22)),
1358 				.flags = IGNORE_GPR(20),
1359 				.regs = {
1360 					.gpr[21] = LONG_MIN,
1361 					.gpr[22] = LONG_MIN,
1362 				}
1363 			},
1364 			{
1365 				.descr = "RA = 1L, RB = 0",
1366 				.instr = ppc_inst(PPC_RAW_DIVDEU(20, 21, 22)),
1367 				.flags = IGNORE_GPR(20),
1368 				.regs = {
1369 					.gpr[21] = 1L,
1370 					.gpr[22] = 0,
1371 				}
1372 			},
1373 			{
1374 				.descr = "RA = LONG_MIN, RB = LONG_MAX",
1375 				.instr = ppc_inst(PPC_RAW_DIVDEU(20, 21, 22)),
1376 				.regs = {
1377 					.gpr[21] = LONG_MIN,
1378 					.gpr[22] = LONG_MAX,
1379 				}
1380 			},
1381 			{
1382 				.descr = "RA = LONG_MAX - 1, RB = LONG_MAX",
1383 				.instr = ppc_inst(PPC_RAW_DIVDEU(20, 21, 22)),
1384 				.regs = {
1385 					.gpr[21] = LONG_MAX - 1,
1386 					.gpr[22] = LONG_MAX,
1387 				}
1388 			},
1389 			{
1390 				.descr = "RA = LONG_MIN + 1, RB = LONG_MIN",
1391 				.instr = ppc_inst(PPC_RAW_DIVDEU(20, 21, 22)),
1392 				.flags = IGNORE_GPR(20),
1393 				.regs = {
1394 					.gpr[21] = LONG_MIN + 1,
1395 					.gpr[22] = LONG_MIN,
1396 				}
1397 			}
1398 		}
1399 	},
1400 	{
1401 		.mnemonic = "divdeu.",
1402 		.subtests = {
1403 			{
1404 				.descr = "RA = LONG_MIN, RB = LONG_MIN",
1405 				.instr = ppc_inst(PPC_RAW_DIVDEU_DOT(20, 21, 22)),
1406 				.flags = IGNORE_GPR(20),
1407 				.regs = {
1408 					.gpr[21] = LONG_MIN,
1409 					.gpr[22] = LONG_MIN,
1410 				}
1411 			},
1412 			{
1413 				.descr = "RA = 1L, RB = 0",
1414 				.instr = ppc_inst(PPC_RAW_DIVDEU_DOT(20, 21, 22)),
1415 				.flags = IGNORE_GPR(20),
1416 				.regs = {
1417 					.gpr[21] = 1L,
1418 					.gpr[22] = 0,
1419 				}
1420 			},
1421 			{
1422 				.descr = "RA = LONG_MIN, RB = LONG_MAX",
1423 				.instr = ppc_inst(PPC_RAW_DIVDEU_DOT(20, 21, 22)),
1424 				.regs = {
1425 					.gpr[21] = LONG_MIN,
1426 					.gpr[22] = LONG_MAX,
1427 				}
1428 			},
1429 			{
1430 				.descr = "RA = LONG_MAX - 1, RB = LONG_MAX",
1431 				.instr = ppc_inst(PPC_RAW_DIVDEU_DOT(20, 21, 22)),
1432 				.regs = {
1433 					.gpr[21] = LONG_MAX - 1,
1434 					.gpr[22] = LONG_MAX,
1435 				}
1436 			},
1437 			{
1438 				.descr = "RA = LONG_MIN + 1, RB = LONG_MIN",
1439 				.instr = ppc_inst(PPC_RAW_DIVDEU_DOT(20, 21, 22)),
1440 				.flags = IGNORE_GPR(20),
1441 				.regs = {
1442 					.gpr[21] = LONG_MIN + 1,
1443 					.gpr[22] = LONG_MIN,
1444 				}
1445 			}
1446 		}
1447 	},
1448 	{
1449 		.mnemonic = "paddi",
1450 		.cpu_feature = CPU_FTR_ARCH_31,
1451 		.subtests = {
1452 			{
1453 				.descr = "RA = LONG_MIN, SI = SI_MIN, R = 0",
1454 				.instr = TEST_PADDI(21, 22, SI_MIN, 0),
1455 				.regs = {
1456 					.gpr[21] = 0,
1457 					.gpr[22] = LONG_MIN,
1458 				}
1459 			},
1460 			{
1461 				.descr = "RA = LONG_MIN, SI = SI_MAX, R = 0",
1462 				.instr = TEST_PADDI(21, 22, SI_MAX, 0),
1463 				.regs = {
1464 					.gpr[21] = 0,
1465 					.gpr[22] = LONG_MIN,
1466 				}
1467 			},
1468 			{
1469 				.descr = "RA = LONG_MAX, SI = SI_MAX, R = 0",
1470 				.instr = TEST_PADDI(21, 22, SI_MAX, 0),
1471 				.regs = {
1472 					.gpr[21] = 0,
1473 					.gpr[22] = LONG_MAX,
1474 				}
1475 			},
1476 			{
1477 				.descr = "RA = ULONG_MAX, SI = SI_UMAX, R = 0",
1478 				.instr = TEST_PADDI(21, 22, SI_UMAX, 0),
1479 				.regs = {
1480 					.gpr[21] = 0,
1481 					.gpr[22] = ULONG_MAX,
1482 				}
1483 			},
1484 			{
1485 				.descr = "RA = ULONG_MAX, SI = 0x1, R = 0",
1486 				.instr = TEST_PADDI(21, 22, 0x1, 0),
1487 				.regs = {
1488 					.gpr[21] = 0,
1489 					.gpr[22] = ULONG_MAX,
1490 				}
1491 			},
1492 			{
1493 				.descr = "RA = INT_MIN, SI = SI_MIN, R = 0",
1494 				.instr = TEST_PADDI(21, 22, SI_MIN, 0),
1495 				.regs = {
1496 					.gpr[21] = 0,
1497 					.gpr[22] = INT_MIN,
1498 				}
1499 			},
1500 			{
1501 				.descr = "RA = INT_MIN, SI = SI_MAX, R = 0",
1502 				.instr = TEST_PADDI(21, 22, SI_MAX, 0),
1503 				.regs = {
1504 					.gpr[21] = 0,
1505 					.gpr[22] = INT_MIN,
1506 				}
1507 			},
1508 			{
1509 				.descr = "RA = INT_MAX, SI = SI_MAX, R = 0",
1510 				.instr = TEST_PADDI(21, 22, SI_MAX, 0),
1511 				.regs = {
1512 					.gpr[21] = 0,
1513 					.gpr[22] = INT_MAX,
1514 				}
1515 			},
1516 			{
1517 				.descr = "RA = UINT_MAX, SI = 0x1, R = 0",
1518 				.instr = TEST_PADDI(21, 22, 0x1, 0),
1519 				.regs = {
1520 					.gpr[21] = 0,
1521 					.gpr[22] = UINT_MAX,
1522 				}
1523 			},
1524 			{
1525 				.descr = "RA = UINT_MAX, SI = SI_MAX, R = 0",
1526 				.instr = TEST_PADDI(21, 22, SI_MAX, 0),
1527 				.regs = {
1528 					.gpr[21] = 0,
1529 					.gpr[22] = UINT_MAX,
1530 				}
1531 			},
1532 			{
1533 				.descr = "RA is r0, SI = SI_MIN, R = 0",
1534 				.instr = TEST_PADDI(21, 0, SI_MIN, 0),
1535 				.regs = {
1536 					.gpr[21] = 0x0,
1537 				}
1538 			},
1539 			{
1540 				.descr = "RA = 0, SI = SI_MIN, R = 0",
1541 				.instr = TEST_PADDI(21, 22, SI_MIN, 0),
1542 				.regs = {
1543 					.gpr[21] = 0x0,
1544 					.gpr[22] = 0x0,
1545 				}
1546 			},
1547 			{
1548 				.descr = "RA is r0, SI = 0, R = 1",
1549 				.instr = TEST_PADDI(21, 0, 0, 1),
1550 				.regs = {
1551 					.gpr[21] = 0,
1552 				}
1553 			},
1554 			{
1555 				.descr = "RA is r0, SI = SI_MIN, R = 1",
1556 				.instr = TEST_PADDI(21, 0, SI_MIN, 1),
1557 				.regs = {
1558 					.gpr[21] = 0,
1559 				}
1560 			},
1561 			/* Invalid instruction form with R = 1 and RA != 0 */
1562 			{
1563 				.descr = "RA = R22(0), SI = 0, R = 1",
1564 				.instr = TEST_PADDI(21, 22, 0, 1),
1565 				.flags = NEGATIVE_TEST,
1566 				.regs = {
1567 					.gpr[21] = 0,
1568 					.gpr[22] = 0,
1569 				}
1570 			}
1571 		}
1572 	}
1573 };
1574 
1575 static int __init emulate_compute_instr(struct pt_regs *regs,
1576 					struct ppc_inst instr,
1577 					bool negative)
1578 {
1579 	int analysed;
1580 	struct instruction_op op;
1581 
1582 	if (!regs || !ppc_inst_val(instr))
1583 		return -EINVAL;
1584 
1585 	regs->nip = patch_site_addr(&patch__exec_instr);
1586 
1587 	analysed = analyse_instr(&op, regs, instr);
1588 	if (analysed != 1 || GETTYPE(op.type) != COMPUTE) {
1589 		if (negative)
1590 			return -EFAULT;
1591 		pr_info("emulation failed, instruction = %s\n", ppc_inst_as_str(instr));
1592 		return -EFAULT;
1593 	}
1594 	if (analysed == 1 && negative)
1595 		pr_info("negative test failed, instruction = %s\n", ppc_inst_as_str(instr));
1596 	if (!negative)
1597 		emulate_update_regs(regs, &op);
1598 	return 0;
1599 }
1600 
1601 static int __init execute_compute_instr(struct pt_regs *regs,
1602 					struct ppc_inst instr)
1603 {
1604 	extern int exec_instr(struct pt_regs *regs);
1605 
1606 	if (!regs || !ppc_inst_val(instr))
1607 		return -EINVAL;
1608 
1609 	/* Patch the NOP with the actual instruction */
1610 	patch_instruction_site(&patch__exec_instr, instr);
1611 	if (exec_instr(regs)) {
1612 		pr_info("execution failed, instruction = %s\n", ppc_inst_as_str(instr));
1613 		return -EFAULT;
1614 	}
1615 
1616 	return 0;
1617 }
1618 
1619 #define gpr_mismatch(gprn, exp, got)	\
1620 	pr_info("GPR%u mismatch, exp = 0x%016lx, got = 0x%016lx\n",	\
1621 		gprn, exp, got)
1622 
1623 #define reg_mismatch(name, exp, got)	\
1624 	pr_info("%s mismatch, exp = 0x%016lx, got = 0x%016lx\n",	\
1625 		name, exp, got)
1626 
1627 static void __init run_tests_compute(void)
1628 {
1629 	unsigned long flags;
1630 	struct compute_test *test;
1631 	struct pt_regs *regs, exp, got;
1632 	unsigned int i, j, k;
1633 	struct ppc_inst instr;
1634 	bool ignore_gpr, ignore_xer, ignore_ccr, passed, rc, negative;
1635 
1636 	for (i = 0; i < ARRAY_SIZE(compute_tests); i++) {
1637 		test = &compute_tests[i];
1638 
1639 		if (test->cpu_feature && !early_cpu_has_feature(test->cpu_feature)) {
1640 			show_result(test->mnemonic, "SKIP (!CPU_FTR)");
1641 			continue;
1642 		}
1643 
1644 		for (j = 0; j < MAX_SUBTESTS && test->subtests[j].descr; j++) {
1645 			instr = test->subtests[j].instr;
1646 			flags = test->subtests[j].flags;
1647 			regs = &test->subtests[j].regs;
1648 			negative = flags & NEGATIVE_TEST;
1649 			ignore_xer = flags & IGNORE_XER;
1650 			ignore_ccr = flags & IGNORE_CCR;
1651 			passed = true;
1652 
1653 			memcpy(&exp, regs, sizeof(struct pt_regs));
1654 			memcpy(&got, regs, sizeof(struct pt_regs));
1655 
1656 			/*
1657 			 * Set a compatible MSR value explicitly to ensure
1658 			 * that XER and CR bits are updated appropriately
1659 			 */
1660 			exp.msr = MSR_KERNEL;
1661 			got.msr = MSR_KERNEL;
1662 
1663 			rc = emulate_compute_instr(&got, instr, negative) != 0;
1664 			if (negative) {
1665 				/* skip executing instruction */
1666 				passed = rc;
1667 				goto print;
1668 			} else if (rc || execute_compute_instr(&exp, instr)) {
1669 				passed = false;
1670 				goto print;
1671 			}
1672 
1673 			/* Verify GPR values */
1674 			for (k = 0; k < 32; k++) {
1675 				ignore_gpr = flags & IGNORE_GPR(k);
1676 				if (!ignore_gpr && exp.gpr[k] != got.gpr[k]) {
1677 					passed = false;
1678 					gpr_mismatch(k, exp.gpr[k], got.gpr[k]);
1679 				}
1680 			}
1681 
1682 			/* Verify LR value */
1683 			if (exp.link != got.link) {
1684 				passed = false;
1685 				reg_mismatch("LR", exp.link, got.link);
1686 			}
1687 
1688 			/* Verify XER value */
1689 			if (!ignore_xer && exp.xer != got.xer) {
1690 				passed = false;
1691 				reg_mismatch("XER", exp.xer, got.xer);
1692 			}
1693 
1694 			/* Verify CR value */
1695 			if (!ignore_ccr && exp.ccr != got.ccr) {
1696 				passed = false;
1697 				reg_mismatch("CR", exp.ccr, got.ccr);
1698 			}
1699 
1700 print:
1701 			show_result_with_descr(test->mnemonic,
1702 					       test->subtests[j].descr,
1703 					       passed ? "PASS" : "FAIL");
1704 		}
1705 	}
1706 }
1707 
1708 static int __init test_emulate_step(void)
1709 {
1710 	printk(KERN_INFO "Running instruction emulation self-tests ...\n");
1711 	run_tests_load_store();
1712 	run_tests_compute();
1713 
1714 	return 0;
1715 }
1716 late_initcall(test_emulate_step);
1717