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