GNU Linux-libre 5.10.217-gnu1
[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
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 static void __init run_tests_load_store(void)
616 {
617         test_ld();
618         test_pld();
619         test_lwz();
620         test_plwz();
621         test_lwzx();
622         test_std();
623         test_pstd();
624         test_ldarx_stdcx();
625         test_lfsx_stfsx();
626         test_plfs_pstfs();
627         test_lfdx_stfdx();
628         test_plfd_pstfd();
629         test_lvx_stvx();
630         test_lxvd2x_stxvd2x();
631 }
632
633 struct compute_test {
634         char *mnemonic;
635         unsigned long cpu_feature;
636         struct {
637                 char *descr;
638                 unsigned long flags;
639                 struct ppc_inst instr;
640                 struct pt_regs regs;
641         } subtests[MAX_SUBTESTS + 1];
642 };
643
644 /* Extreme values for si0||si1 (the MLS:D-form 34 bit immediate field) */
645 #define SI_MIN BIT(33)
646 #define SI_MAX (BIT(33) - 1)
647 #define SI_UMAX (BIT(34) - 1)
648
649 static struct compute_test compute_tests[] = {
650         {
651                 .mnemonic = "nop",
652                 .subtests = {
653                         {
654                                 .descr = "R0 = LONG_MAX",
655                                 .instr = ppc_inst(PPC_INST_NOP),
656                                 .regs = {
657                                         .gpr[0] = LONG_MAX,
658                                 }
659                         }
660                 }
661         },
662         {
663                 .mnemonic = "add",
664                 .subtests = {
665                         {
666                                 .descr = "RA = LONG_MIN, RB = LONG_MIN",
667                                 .instr = ppc_inst(PPC_RAW_ADD(20, 21, 22)),
668                                 .regs = {
669                                         .gpr[21] = LONG_MIN,
670                                         .gpr[22] = LONG_MIN,
671                                 }
672                         },
673                         {
674                                 .descr = "RA = LONG_MIN, RB = LONG_MAX",
675                                 .instr = ppc_inst(PPC_RAW_ADD(20, 21, 22)),
676                                 .regs = {
677                                         .gpr[21] = LONG_MIN,
678                                         .gpr[22] = LONG_MAX,
679                                 }
680                         },
681                         {
682                                 .descr = "RA = LONG_MAX, RB = LONG_MAX",
683                                 .instr = ppc_inst(PPC_RAW_ADD(20, 21, 22)),
684                                 .regs = {
685                                         .gpr[21] = LONG_MAX,
686                                         .gpr[22] = LONG_MAX,
687                                 }
688                         },
689                         {
690                                 .descr = "RA = ULONG_MAX, RB = ULONG_MAX",
691                                 .instr = ppc_inst(PPC_RAW_ADD(20, 21, 22)),
692                                 .regs = {
693                                         .gpr[21] = ULONG_MAX,
694                                         .gpr[22] = ULONG_MAX,
695                                 }
696                         },
697                         {
698                                 .descr = "RA = ULONG_MAX, RB = 0x1",
699                                 .instr = ppc_inst(PPC_RAW_ADD(20, 21, 22)),
700                                 .regs = {
701                                         .gpr[21] = ULONG_MAX,
702                                         .gpr[22] = 0x1,
703                                 }
704                         },
705                         {
706                                 .descr = "RA = INT_MIN, RB = INT_MIN",
707                                 .instr = ppc_inst(PPC_RAW_ADD(20, 21, 22)),
708                                 .regs = {
709                                         .gpr[21] = INT_MIN,
710                                         .gpr[22] = INT_MIN,
711                                 }
712                         },
713                         {
714                                 .descr = "RA = INT_MIN, RB = INT_MAX",
715                                 .instr = ppc_inst(PPC_RAW_ADD(20, 21, 22)),
716                                 .regs = {
717                                         .gpr[21] = INT_MIN,
718                                         .gpr[22] = INT_MAX,
719                                 }
720                         },
721                         {
722                                 .descr = "RA = INT_MAX, RB = INT_MAX",
723                                 .instr = ppc_inst(PPC_RAW_ADD(20, 21, 22)),
724                                 .regs = {
725                                         .gpr[21] = INT_MAX,
726                                         .gpr[22] = INT_MAX,
727                                 }
728                         },
729                         {
730                                 .descr = "RA = UINT_MAX, RB = UINT_MAX",
731                                 .instr = ppc_inst(PPC_RAW_ADD(20, 21, 22)),
732                                 .regs = {
733                                         .gpr[21] = UINT_MAX,
734                                         .gpr[22] = UINT_MAX,
735                                 }
736                         },
737                         {
738                                 .descr = "RA = UINT_MAX, RB = 0x1",
739                                 .instr = ppc_inst(PPC_RAW_ADD(20, 21, 22)),
740                                 .regs = {
741                                         .gpr[21] = UINT_MAX,
742                                         .gpr[22] = 0x1,
743                                 }
744                         }
745                 }
746         },
747         {
748                 .mnemonic = "add.",
749                 .subtests = {
750                         {
751                                 .descr = "RA = LONG_MIN, RB = LONG_MIN",
752                                 .flags = IGNORE_CCR,
753                                 .instr = ppc_inst(PPC_RAW_ADD_DOT(20, 21, 22)),
754                                 .regs = {
755                                         .gpr[21] = LONG_MIN,
756                                         .gpr[22] = LONG_MIN,
757                                 }
758                         },
759                         {
760                                 .descr = "RA = LONG_MIN, RB = LONG_MAX",
761                                 .instr = ppc_inst(PPC_RAW_ADD_DOT(20, 21, 22)),
762                                 .regs = {
763                                         .gpr[21] = LONG_MIN,
764                                         .gpr[22] = LONG_MAX,
765                                 }
766                         },
767                         {
768                                 .descr = "RA = LONG_MAX, RB = LONG_MAX",
769                                 .flags = IGNORE_CCR,
770                                 .instr = ppc_inst(PPC_RAW_ADD_DOT(20, 21, 22)),
771                                 .regs = {
772                                         .gpr[21] = LONG_MAX,
773                                         .gpr[22] = LONG_MAX,
774                                 }
775                         },
776                         {
777                                 .descr = "RA = ULONG_MAX, RB = ULONG_MAX",
778                                 .instr = ppc_inst(PPC_RAW_ADD_DOT(20, 21, 22)),
779                                 .regs = {
780                                         .gpr[21] = ULONG_MAX,
781                                         .gpr[22] = ULONG_MAX,
782                                 }
783                         },
784                         {
785                                 .descr = "RA = ULONG_MAX, RB = 0x1",
786                                 .instr = ppc_inst(PPC_RAW_ADD_DOT(20, 21, 22)),
787                                 .regs = {
788                                         .gpr[21] = ULONG_MAX,
789                                         .gpr[22] = 0x1,
790                                 }
791                         },
792                         {
793                                 .descr = "RA = INT_MIN, RB = INT_MIN",
794                                 .instr = ppc_inst(PPC_RAW_ADD_DOT(20, 21, 22)),
795                                 .regs = {
796                                         .gpr[21] = INT_MIN,
797                                         .gpr[22] = INT_MIN,
798                                 }
799                         },
800                         {
801                                 .descr = "RA = INT_MIN, RB = INT_MAX",
802                                 .instr = ppc_inst(PPC_RAW_ADD_DOT(20, 21, 22)),
803                                 .regs = {
804                                         .gpr[21] = INT_MIN,
805                                         .gpr[22] = INT_MAX,
806                                 }
807                         },
808                         {
809                                 .descr = "RA = INT_MAX, RB = INT_MAX",
810                                 .instr = ppc_inst(PPC_RAW_ADD_DOT(20, 21, 22)),
811                                 .regs = {
812                                         .gpr[21] = INT_MAX,
813                                         .gpr[22] = INT_MAX,
814                                 }
815                         },
816                         {
817                                 .descr = "RA = UINT_MAX, RB = UINT_MAX",
818                                 .instr = ppc_inst(PPC_RAW_ADD_DOT(20, 21, 22)),
819                                 .regs = {
820                                         .gpr[21] = UINT_MAX,
821                                         .gpr[22] = UINT_MAX,
822                                 }
823                         },
824                         {
825                                 .descr = "RA = UINT_MAX, RB = 0x1",
826                                 .instr = ppc_inst(PPC_RAW_ADD_DOT(20, 21, 22)),
827                                 .regs = {
828                                         .gpr[21] = UINT_MAX,
829                                         .gpr[22] = 0x1,
830                                 }
831                         }
832                 }
833         },
834         {
835                 .mnemonic = "addc",
836                 .subtests = {
837                         {
838                                 .descr = "RA = LONG_MIN, RB = LONG_MIN",
839                                 .instr = ppc_inst(PPC_RAW_ADDC(20, 21, 22)),
840                                 .regs = {
841                                         .gpr[21] = LONG_MIN,
842                                         .gpr[22] = LONG_MIN,
843                                 }
844                         },
845                         {
846                                 .descr = "RA = LONG_MIN, RB = LONG_MAX",
847                                 .instr = ppc_inst(PPC_RAW_ADDC(20, 21, 22)),
848                                 .regs = {
849                                         .gpr[21] = LONG_MIN,
850                                         .gpr[22] = LONG_MAX,
851                                 }
852                         },
853                         {
854                                 .descr = "RA = LONG_MAX, RB = LONG_MAX",
855                                 .instr = ppc_inst(PPC_RAW_ADDC(20, 21, 22)),
856                                 .regs = {
857                                         .gpr[21] = LONG_MAX,
858                                         .gpr[22] = LONG_MAX,
859                                 }
860                         },
861                         {
862                                 .descr = "RA = ULONG_MAX, RB = ULONG_MAX",
863                                 .instr = ppc_inst(PPC_RAW_ADDC(20, 21, 22)),
864                                 .regs = {
865                                         .gpr[21] = ULONG_MAX,
866                                         .gpr[22] = ULONG_MAX,
867                                 }
868                         },
869                         {
870                                 .descr = "RA = ULONG_MAX, RB = 0x1",
871                                 .instr = ppc_inst(PPC_RAW_ADDC(20, 21, 22)),
872                                 .regs = {
873                                         .gpr[21] = ULONG_MAX,
874                                         .gpr[22] = 0x1,
875                                 }
876                         },
877                         {
878                                 .descr = "RA = INT_MIN, RB = INT_MIN",
879                                 .instr = ppc_inst(PPC_RAW_ADDC(20, 21, 22)),
880                                 .regs = {
881                                         .gpr[21] = INT_MIN,
882                                         .gpr[22] = INT_MIN,
883                                 }
884                         },
885                         {
886                                 .descr = "RA = INT_MIN, RB = INT_MAX",
887                                 .instr = ppc_inst(PPC_RAW_ADDC(20, 21, 22)),
888                                 .regs = {
889                                         .gpr[21] = INT_MIN,
890                                         .gpr[22] = INT_MAX,
891                                 }
892                         },
893                         {
894                                 .descr = "RA = INT_MAX, RB = INT_MAX",
895                                 .instr = ppc_inst(PPC_RAW_ADDC(20, 21, 22)),
896                                 .regs = {
897                                         .gpr[21] = INT_MAX,
898                                         .gpr[22] = INT_MAX,
899                                 }
900                         },
901                         {
902                                 .descr = "RA = UINT_MAX, RB = UINT_MAX",
903                                 .instr = ppc_inst(PPC_RAW_ADDC(20, 21, 22)),
904                                 .regs = {
905                                         .gpr[21] = UINT_MAX,
906                                         .gpr[22] = UINT_MAX,
907                                 }
908                         },
909                         {
910                                 .descr = "RA = UINT_MAX, RB = 0x1",
911                                 .instr = ppc_inst(PPC_RAW_ADDC(20, 21, 22)),
912                                 .regs = {
913                                         .gpr[21] = UINT_MAX,
914                                         .gpr[22] = 0x1,
915                                 }
916                         },
917                         {
918                                 .descr = "RA = LONG_MIN | INT_MIN, RB = LONG_MIN | INT_MIN",
919                                 .instr = ppc_inst(PPC_RAW_ADDC(20, 21, 22)),
920                                 .regs = {
921                                         .gpr[21] = LONG_MIN | (uint)INT_MIN,
922                                         .gpr[22] = LONG_MIN | (uint)INT_MIN,
923                                 }
924                         }
925                 }
926         },
927         {
928                 .mnemonic = "addc.",
929                 .subtests = {
930                         {
931                                 .descr = "RA = LONG_MIN, RB = LONG_MIN",
932                                 .flags = IGNORE_CCR,
933                                 .instr = ppc_inst(PPC_RAW_ADDC_DOT(20, 21, 22)),
934                                 .regs = {
935                                         .gpr[21] = LONG_MIN,
936                                         .gpr[22] = LONG_MIN,
937                                 }
938                         },
939                         {
940                                 .descr = "RA = LONG_MIN, RB = LONG_MAX",
941                                 .instr = ppc_inst(PPC_RAW_ADDC_DOT(20, 21, 22)),
942                                 .regs = {
943                                         .gpr[21] = LONG_MIN,
944                                         .gpr[22] = LONG_MAX,
945                                 }
946                         },
947                         {
948                                 .descr = "RA = LONG_MAX, RB = LONG_MAX",
949                                 .flags = IGNORE_CCR,
950                                 .instr = ppc_inst(PPC_RAW_ADDC_DOT(20, 21, 22)),
951                                 .regs = {
952                                         .gpr[21] = LONG_MAX,
953                                         .gpr[22] = LONG_MAX,
954                                 }
955                         },
956                         {
957                                 .descr = "RA = ULONG_MAX, RB = ULONG_MAX",
958                                 .instr = ppc_inst(PPC_RAW_ADDC_DOT(20, 21, 22)),
959                                 .regs = {
960                                         .gpr[21] = ULONG_MAX,
961                                         .gpr[22] = ULONG_MAX,
962                                 }
963                         },
964                         {
965                                 .descr = "RA = ULONG_MAX, RB = 0x1",
966                                 .instr = ppc_inst(PPC_RAW_ADDC_DOT(20, 21, 22)),
967                                 .regs = {
968                                         .gpr[21] = ULONG_MAX,
969                                         .gpr[22] = 0x1,
970                                 }
971                         },
972                         {
973                                 .descr = "RA = INT_MIN, RB = INT_MIN",
974                                 .instr = ppc_inst(PPC_RAW_ADDC_DOT(20, 21, 22)),
975                                 .regs = {
976                                         .gpr[21] = INT_MIN,
977                                         .gpr[22] = INT_MIN,
978                                 }
979                         },
980                         {
981                                 .descr = "RA = INT_MIN, RB = INT_MAX",
982                                 .instr = ppc_inst(PPC_RAW_ADDC_DOT(20, 21, 22)),
983                                 .regs = {
984                                         .gpr[21] = INT_MIN,
985                                         .gpr[22] = INT_MAX,
986                                 }
987                         },
988                         {
989                                 .descr = "RA = INT_MAX, RB = INT_MAX",
990                                 .instr = ppc_inst(PPC_RAW_ADDC_DOT(20, 21, 22)),
991                                 .regs = {
992                                         .gpr[21] = INT_MAX,
993                                         .gpr[22] = INT_MAX,
994                                 }
995                         },
996                         {
997                                 .descr = "RA = UINT_MAX, RB = UINT_MAX",
998                                 .instr = ppc_inst(PPC_RAW_ADDC_DOT(20, 21, 22)),
999                                 .regs = {
1000                                         .gpr[21] = UINT_MAX,
1001                                         .gpr[22] = UINT_MAX,
1002                                 }
1003                         },
1004                         {
1005                                 .descr = "RA = UINT_MAX, RB = 0x1",
1006                                 .instr = ppc_inst(PPC_RAW_ADDC_DOT(20, 21, 22)),
1007                                 .regs = {
1008                                         .gpr[21] = UINT_MAX,
1009                                         .gpr[22] = 0x1,
1010                                 }
1011                         },
1012                         {
1013                                 .descr = "RA = LONG_MIN | INT_MIN, RB = LONG_MIN | INT_MIN",
1014                                 .instr = ppc_inst(PPC_RAW_ADDC_DOT(20, 21, 22)),
1015                                 .regs = {
1016                                         .gpr[21] = LONG_MIN | (uint)INT_MIN,
1017                                         .gpr[22] = LONG_MIN | (uint)INT_MIN,
1018                                 }
1019                         }
1020                 }
1021         },
1022         {
1023                 .mnemonic = "divde",
1024                 .subtests = {
1025                         {
1026                                 .descr = "RA = LONG_MIN, RB = LONG_MIN",
1027                                 .instr = ppc_inst(PPC_RAW_DIVDE(20, 21, 22)),
1028                                 .regs = {
1029                                         .gpr[21] = LONG_MIN,
1030                                         .gpr[22] = LONG_MIN,
1031                                 }
1032                         },
1033                         {
1034                                 .descr = "RA = 1L, RB = 0",
1035                                 .instr = ppc_inst(PPC_RAW_DIVDE(20, 21, 22)),
1036                                 .flags = IGNORE_GPR(20),
1037                                 .regs = {
1038                                         .gpr[21] = 1L,
1039                                         .gpr[22] = 0,
1040                                 }
1041                         },
1042                         {
1043                                 .descr = "RA = LONG_MIN, RB = LONG_MAX",
1044                                 .instr = ppc_inst(PPC_RAW_DIVDE(20, 21, 22)),
1045                                 .regs = {
1046                                         .gpr[21] = LONG_MIN,
1047                                         .gpr[22] = LONG_MAX,
1048                                 }
1049                         }
1050                 }
1051         },
1052         {
1053                 .mnemonic = "divde.",
1054                 .subtests = {
1055                         {
1056                                 .descr = "RA = LONG_MIN, RB = LONG_MIN",
1057                                 .instr = ppc_inst(PPC_RAW_DIVDE_DOT(20, 21, 22)),
1058                                 .regs = {
1059                                         .gpr[21] = LONG_MIN,
1060                                         .gpr[22] = LONG_MIN,
1061                                 }
1062                         },
1063                         {
1064                                 .descr = "RA = 1L, RB = 0",
1065                                 .instr = ppc_inst(PPC_RAW_DIVDE_DOT(20, 21, 22)),
1066                                 .flags = IGNORE_GPR(20),
1067                                 .regs = {
1068                                         .gpr[21] = 1L,
1069                                         .gpr[22] = 0,
1070                                 }
1071                         },
1072                         {
1073                                 .descr = "RA = LONG_MIN, RB = LONG_MAX",
1074                                 .instr = ppc_inst(PPC_RAW_DIVDE_DOT(20, 21, 22)),
1075                                 .regs = {
1076                                         .gpr[21] = LONG_MIN,
1077                                         .gpr[22] = LONG_MAX,
1078                                 }
1079                         }
1080                 }
1081         },
1082         {
1083                 .mnemonic = "divdeu",
1084                 .subtests = {
1085                         {
1086                                 .descr = "RA = LONG_MIN, RB = LONG_MIN",
1087                                 .instr = ppc_inst(PPC_RAW_DIVDEU(20, 21, 22)),
1088                                 .flags = IGNORE_GPR(20),
1089                                 .regs = {
1090                                         .gpr[21] = LONG_MIN,
1091                                         .gpr[22] = LONG_MIN,
1092                                 }
1093                         },
1094                         {
1095                                 .descr = "RA = 1L, RB = 0",
1096                                 .instr = ppc_inst(PPC_RAW_DIVDEU(20, 21, 22)),
1097                                 .flags = IGNORE_GPR(20),
1098                                 .regs = {
1099                                         .gpr[21] = 1L,
1100                                         .gpr[22] = 0,
1101                                 }
1102                         },
1103                         {
1104                                 .descr = "RA = LONG_MIN, RB = LONG_MAX",
1105                                 .instr = ppc_inst(PPC_RAW_DIVDEU(20, 21, 22)),
1106                                 .regs = {
1107                                         .gpr[21] = LONG_MIN,
1108                                         .gpr[22] = LONG_MAX,
1109                                 }
1110                         },
1111                         {
1112                                 .descr = "RA = LONG_MAX - 1, RB = LONG_MAX",
1113                                 .instr = ppc_inst(PPC_RAW_DIVDEU(20, 21, 22)),
1114                                 .regs = {
1115                                         .gpr[21] = LONG_MAX - 1,
1116                                         .gpr[22] = LONG_MAX,
1117                                 }
1118                         },
1119                         {
1120                                 .descr = "RA = LONG_MIN + 1, RB = LONG_MIN",
1121                                 .instr = ppc_inst(PPC_RAW_DIVDEU(20, 21, 22)),
1122                                 .flags = IGNORE_GPR(20),
1123                                 .regs = {
1124                                         .gpr[21] = LONG_MIN + 1,
1125                                         .gpr[22] = LONG_MIN,
1126                                 }
1127                         }
1128                 }
1129         },
1130         {
1131                 .mnemonic = "divdeu.",
1132                 .subtests = {
1133                         {
1134                                 .descr = "RA = LONG_MIN, RB = LONG_MIN",
1135                                 .instr = ppc_inst(PPC_RAW_DIVDEU_DOT(20, 21, 22)),
1136                                 .flags = IGNORE_GPR(20),
1137                                 .regs = {
1138                                         .gpr[21] = LONG_MIN,
1139                                         .gpr[22] = LONG_MIN,
1140                                 }
1141                         },
1142                         {
1143                                 .descr = "RA = 1L, RB = 0",
1144                                 .instr = ppc_inst(PPC_RAW_DIVDEU_DOT(20, 21, 22)),
1145                                 .flags = IGNORE_GPR(20),
1146                                 .regs = {
1147                                         .gpr[21] = 1L,
1148                                         .gpr[22] = 0,
1149                                 }
1150                         },
1151                         {
1152                                 .descr = "RA = LONG_MIN, RB = LONG_MAX",
1153                                 .instr = ppc_inst(PPC_RAW_DIVDEU_DOT(20, 21, 22)),
1154                                 .regs = {
1155                                         .gpr[21] = LONG_MIN,
1156                                         .gpr[22] = LONG_MAX,
1157                                 }
1158                         },
1159                         {
1160                                 .descr = "RA = LONG_MAX - 1, RB = LONG_MAX",
1161                                 .instr = ppc_inst(PPC_RAW_DIVDEU_DOT(20, 21, 22)),
1162                                 .regs = {
1163                                         .gpr[21] = LONG_MAX - 1,
1164                                         .gpr[22] = LONG_MAX,
1165                                 }
1166                         },
1167                         {
1168                                 .descr = "RA = LONG_MIN + 1, RB = LONG_MIN",
1169                                 .instr = ppc_inst(PPC_RAW_DIVDEU_DOT(20, 21, 22)),
1170                                 .flags = IGNORE_GPR(20),
1171                                 .regs = {
1172                                         .gpr[21] = LONG_MIN + 1,
1173                                         .gpr[22] = LONG_MIN,
1174                                 }
1175                         }
1176                 }
1177         },
1178         {
1179                 .mnemonic = "paddi",
1180                 .cpu_feature = CPU_FTR_ARCH_31,
1181                 .subtests = {
1182                         {
1183                                 .descr = "RA = LONG_MIN, SI = SI_MIN, R = 0",
1184                                 .instr = TEST_PADDI(21, 22, SI_MIN, 0),
1185                                 .regs = {
1186                                         .gpr[21] = 0,
1187                                         .gpr[22] = LONG_MIN,
1188                                 }
1189                         },
1190                         {
1191                                 .descr = "RA = LONG_MIN, SI = SI_MAX, R = 0",
1192                                 .instr = TEST_PADDI(21, 22, SI_MAX, 0),
1193                                 .regs = {
1194                                         .gpr[21] = 0,
1195                                         .gpr[22] = LONG_MIN,
1196                                 }
1197                         },
1198                         {
1199                                 .descr = "RA = LONG_MAX, SI = SI_MAX, R = 0",
1200                                 .instr = TEST_PADDI(21, 22, SI_MAX, 0),
1201                                 .regs = {
1202                                         .gpr[21] = 0,
1203                                         .gpr[22] = LONG_MAX,
1204                                 }
1205                         },
1206                         {
1207                                 .descr = "RA = ULONG_MAX, SI = SI_UMAX, R = 0",
1208                                 .instr = TEST_PADDI(21, 22, SI_UMAX, 0),
1209                                 .regs = {
1210                                         .gpr[21] = 0,
1211                                         .gpr[22] = ULONG_MAX,
1212                                 }
1213                         },
1214                         {
1215                                 .descr = "RA = ULONG_MAX, SI = 0x1, R = 0",
1216                                 .instr = TEST_PADDI(21, 22, 0x1, 0),
1217                                 .regs = {
1218                                         .gpr[21] = 0,
1219                                         .gpr[22] = ULONG_MAX,
1220                                 }
1221                         },
1222                         {
1223                                 .descr = "RA = INT_MIN, SI = SI_MIN, R = 0",
1224                                 .instr = TEST_PADDI(21, 22, SI_MIN, 0),
1225                                 .regs = {
1226                                         .gpr[21] = 0,
1227                                         .gpr[22] = INT_MIN,
1228                                 }
1229                         },
1230                         {
1231                                 .descr = "RA = INT_MIN, SI = SI_MAX, R = 0",
1232                                 .instr = TEST_PADDI(21, 22, SI_MAX, 0),
1233                                 .regs = {
1234                                         .gpr[21] = 0,
1235                                         .gpr[22] = INT_MIN,
1236                                 }
1237                         },
1238                         {
1239                                 .descr = "RA = INT_MAX, SI = SI_MAX, R = 0",
1240                                 .instr = TEST_PADDI(21, 22, SI_MAX, 0),
1241                                 .regs = {
1242                                         .gpr[21] = 0,
1243                                         .gpr[22] = INT_MAX,
1244                                 }
1245                         },
1246                         {
1247                                 .descr = "RA = UINT_MAX, SI = 0x1, R = 0",
1248                                 .instr = TEST_PADDI(21, 22, 0x1, 0),
1249                                 .regs = {
1250                                         .gpr[21] = 0,
1251                                         .gpr[22] = UINT_MAX,
1252                                 }
1253                         },
1254                         {
1255                                 .descr = "RA = UINT_MAX, SI = SI_MAX, R = 0",
1256                                 .instr = TEST_PADDI(21, 22, SI_MAX, 0),
1257                                 .regs = {
1258                                         .gpr[21] = 0,
1259                                         .gpr[22] = UINT_MAX,
1260                                 }
1261                         },
1262                         {
1263                                 .descr = "RA is r0, SI = SI_MIN, R = 0",
1264                                 .instr = TEST_PADDI(21, 0, SI_MIN, 0),
1265                                 .regs = {
1266                                         .gpr[21] = 0x0,
1267                                 }
1268                         },
1269                         {
1270                                 .descr = "RA = 0, SI = SI_MIN, R = 0",
1271                                 .instr = TEST_PADDI(21, 22, SI_MIN, 0),
1272                                 .regs = {
1273                                         .gpr[21] = 0x0,
1274                                         .gpr[22] = 0x0,
1275                                 }
1276                         },
1277                         {
1278                                 .descr = "RA is r0, SI = 0, R = 1",
1279                                 .instr = TEST_PADDI(21, 0, 0, 1),
1280                                 .regs = {
1281                                         .gpr[21] = 0,
1282                                 }
1283                         },
1284                         {
1285                                 .descr = "RA is r0, SI = SI_MIN, R = 1",
1286                                 .instr = TEST_PADDI(21, 0, SI_MIN, 1),
1287                                 .regs = {
1288                                         .gpr[21] = 0,
1289                                 }
1290                         },
1291                         /* Invalid instruction form with R = 1 and RA != 0 */
1292                         {
1293                                 .descr = "RA = R22(0), SI = 0, R = 1",
1294                                 .instr = TEST_PADDI(21, 22, 0, 1),
1295                                 .flags = NEGATIVE_TEST,
1296                                 .regs = {
1297                                         .gpr[21] = 0,
1298                                         .gpr[22] = 0,
1299                                 }
1300                         }
1301                 }
1302         }
1303 };
1304
1305 static int __init emulate_compute_instr(struct pt_regs *regs,
1306                                         struct ppc_inst instr,
1307                                         bool negative)
1308 {
1309         int analysed;
1310         struct instruction_op op;
1311
1312         if (!regs || !ppc_inst_val(instr))
1313                 return -EINVAL;
1314
1315         regs->nip = patch_site_addr(&patch__exec_instr);
1316
1317         analysed = analyse_instr(&op, regs, instr);
1318         if (analysed != 1 || GETTYPE(op.type) != COMPUTE) {
1319                 if (negative)
1320                         return -EFAULT;
1321                 pr_info("emulation failed, instruction = %s\n", ppc_inst_as_str(instr));
1322                 return -EFAULT;
1323         }
1324         if (analysed == 1 && negative)
1325                 pr_info("negative test failed, instruction = %s\n", ppc_inst_as_str(instr));
1326         if (!negative)
1327                 emulate_update_regs(regs, &op);
1328         return 0;
1329 }
1330
1331 static int __init execute_compute_instr(struct pt_regs *regs,
1332                                         struct ppc_inst instr)
1333 {
1334         extern int exec_instr(struct pt_regs *regs);
1335
1336         if (!regs || !ppc_inst_val(instr))
1337                 return -EINVAL;
1338
1339         /* Patch the NOP with the actual instruction */
1340         patch_instruction_site(&patch__exec_instr, instr);
1341         if (exec_instr(regs)) {
1342                 pr_info("execution failed, instruction = %s\n", ppc_inst_as_str(instr));
1343                 return -EFAULT;
1344         }
1345
1346         return 0;
1347 }
1348
1349 #define gpr_mismatch(gprn, exp, got)    \
1350         pr_info("GPR%u mismatch, exp = 0x%016lx, got = 0x%016lx\n",     \
1351                 gprn, exp, got)
1352
1353 #define reg_mismatch(name, exp, got)    \
1354         pr_info("%s mismatch, exp = 0x%016lx, got = 0x%016lx\n",        \
1355                 name, exp, got)
1356
1357 static void __init run_tests_compute(void)
1358 {
1359         unsigned long flags;
1360         struct compute_test *test;
1361         struct pt_regs *regs, exp, got;
1362         unsigned int i, j, k;
1363         struct ppc_inst instr;
1364         bool ignore_gpr, ignore_xer, ignore_ccr, passed, rc, negative;
1365
1366         for (i = 0; i < ARRAY_SIZE(compute_tests); i++) {
1367                 test = &compute_tests[i];
1368
1369                 if (test->cpu_feature && !early_cpu_has_feature(test->cpu_feature)) {
1370                         show_result(test->mnemonic, "SKIP (!CPU_FTR)");
1371                         continue;
1372                 }
1373
1374                 for (j = 0; j < MAX_SUBTESTS && test->subtests[j].descr; j++) {
1375                         instr = test->subtests[j].instr;
1376                         flags = test->subtests[j].flags;
1377                         regs = &test->subtests[j].regs;
1378                         negative = flags & NEGATIVE_TEST;
1379                         ignore_xer = flags & IGNORE_XER;
1380                         ignore_ccr = flags & IGNORE_CCR;
1381                         passed = true;
1382
1383                         memcpy(&exp, regs, sizeof(struct pt_regs));
1384                         memcpy(&got, regs, sizeof(struct pt_regs));
1385
1386                         /*
1387                          * Set a compatible MSR value explicitly to ensure
1388                          * that XER and CR bits are updated appropriately
1389                          */
1390                         exp.msr = MSR_KERNEL;
1391                         got.msr = MSR_KERNEL;
1392
1393                         rc = emulate_compute_instr(&got, instr, negative) != 0;
1394                         if (negative) {
1395                                 /* skip executing instruction */
1396                                 passed = rc;
1397                                 goto print;
1398                         } else if (rc || execute_compute_instr(&exp, instr)) {
1399                                 passed = false;
1400                                 goto print;
1401                         }
1402
1403                         /* Verify GPR values */
1404                         for (k = 0; k < 32; k++) {
1405                                 ignore_gpr = flags & IGNORE_GPR(k);
1406                                 if (!ignore_gpr && exp.gpr[k] != got.gpr[k]) {
1407                                         passed = false;
1408                                         gpr_mismatch(k, exp.gpr[k], got.gpr[k]);
1409                                 }
1410                         }
1411
1412                         /* Verify LR value */
1413                         if (exp.link != got.link) {
1414                                 passed = false;
1415                                 reg_mismatch("LR", exp.link, got.link);
1416                         }
1417
1418                         /* Verify XER value */
1419                         if (!ignore_xer && exp.xer != got.xer) {
1420                                 passed = false;
1421                                 reg_mismatch("XER", exp.xer, got.xer);
1422                         }
1423
1424                         /* Verify CR value */
1425                         if (!ignore_ccr && exp.ccr != got.ccr) {
1426                                 passed = false;
1427                                 reg_mismatch("CR", exp.ccr, got.ccr);
1428                         }
1429
1430 print:
1431                         show_result_with_descr(test->mnemonic,
1432                                                test->subtests[j].descr,
1433                                                passed ? "PASS" : "FAIL");
1434                 }
1435         }
1436 }
1437
1438 static int __init test_emulate_step(void)
1439 {
1440         printk(KERN_INFO "Running instruction emulation self-tests ...\n");
1441         run_tests_load_store();
1442         run_tests_compute();
1443
1444         return 0;
1445 }
1446 late_initcall(test_emulate_step);