GNU Linux-libre 5.15.72-gnu
[releases.git] / arch / powerpc / lib / test_emulate_step.c
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         struct ppc_inst 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                 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_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                                         struct ppc_inst 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                                         struct ppc_inst 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         struct ppc_inst 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);