Linux Audio

Check our new training course

Loading...
v4.17
 
  1/*
  2 * Simple sanity test for emulate_step load/store instructions.
  3 *
  4 * Copyright IBM Corp. 2016
  5 *
  6 * This program is free software;  you can redistribute it and/or modify
  7 * it under the terms of the GNU General Public License as published by
  8 * the Free Software Foundation; either version 2 of the License, or
  9 * (at your option) any later version.
 10 */
 11
 12#define pr_fmt(fmt) "emulate_step_test: " fmt
 13
 14#include <linux/ptrace.h>
 
 15#include <asm/sstep.h>
 16#include <asm/ppc-opcode.h>
 
 
 17
 18#define IMM_L(i)		((uintptr_t)(i) & 0xffff)
 19
 20/*
 21 * Defined with TEST_ prefix so it does not conflict with other
 22 * definitions.
 23 */
 24#define TEST_LD(r, base, i)	(PPC_INST_LD | ___PPC_RT(r) |		\
 25					___PPC_RA(base) | IMM_L(i))
 26#define TEST_LWZ(r, base, i)	(PPC_INST_LWZ | ___PPC_RT(r) |		\
 27					___PPC_RA(base) | IMM_L(i))
 28#define TEST_LWZX(t, a, b)	(PPC_INST_LWZX | ___PPC_RT(t) |		\
 29					___PPC_RA(a) | ___PPC_RB(b))
 30#define TEST_STD(r, base, i)	(PPC_INST_STD | ___PPC_RS(r) |		\
 31					___PPC_RA(base) | ((i) & 0xfffc))
 32#define TEST_LDARX(t, a, b, eh)	(PPC_INST_LDARX | ___PPC_RT(t) |	\
 33					___PPC_RA(a) | ___PPC_RB(b) |	\
 34					__PPC_EH(eh))
 35#define TEST_STDCX(s, a, b)	(PPC_INST_STDCX | ___PPC_RS(s) |	\
 36					___PPC_RA(a) | ___PPC_RB(b))
 37#define TEST_LFSX(t, a, b)	(PPC_INST_LFSX | ___PPC_RT(t) |		\
 38					___PPC_RA(a) | ___PPC_RB(b))
 39#define TEST_STFSX(s, a, b)	(PPC_INST_STFSX | ___PPC_RS(s) |	\
 40					___PPC_RA(a) | ___PPC_RB(b))
 41#define TEST_LFDX(t, a, b)	(PPC_INST_LFDX | ___PPC_RT(t) |		\
 42					___PPC_RA(a) | ___PPC_RB(b))
 43#define TEST_STFDX(s, a, b)	(PPC_INST_STFDX | ___PPC_RS(s) |	\
 44					___PPC_RA(a) | ___PPC_RB(b))
 45#define TEST_LVX(t, a, b)	(PPC_INST_LVX | ___PPC_RT(t) |		\
 46					___PPC_RA(a) | ___PPC_RB(b))
 47#define TEST_STVX(s, a, b)	(PPC_INST_STVX | ___PPC_RS(s) |		\
 48					___PPC_RA(a) | ___PPC_RB(b))
 49#define TEST_LXVD2X(s, a, b)	(PPC_INST_LXVD2X | VSX_XX1((s), R##a, R##b))
 50#define TEST_STXVD2X(s, a, b)	(PPC_INST_STXVD2X | VSX_XX1((s), R##a, R##b))
 
 
 
 
 
 51
 52
 53static void __init init_pt_regs(struct pt_regs *regs)
 54{
 55	static unsigned long msr;
 56	static bool msr_cached;
 57
 58	memset(regs, 0, sizeof(struct pt_regs));
 59
 60	if (likely(msr_cached)) {
 61		regs->msr = msr;
 62		return;
 63	}
 64
 65	asm volatile("mfmsr %0" : "=r"(regs->msr));
 66
 67	regs->msr |= MSR_FP;
 68	regs->msr |= MSR_VEC;
 69	regs->msr |= MSR_VSX;
 70
 71	msr = regs->msr;
 72	msr_cached = true;
 73}
 74
 75static void __init show_result(char *ins, char *result)
 
 
 
 
 
 
 76{
 77	pr_info("%-14s : %s\n", ins, result);
 78}
 79
 80static void __init test_ld(void)
 81{
 82	struct pt_regs regs;
 83	unsigned long a = 0x23;
 84	int stepped = -1;
 85
 86	init_pt_regs(&regs);
 87	regs.gpr[3] = (unsigned long) &a;
 88
 89	/* ld r5, 0(r3) */
 90	stepped = emulate_step(&regs, TEST_LD(5, 3, 0));
 91
 92	if (stepped == 1 && regs.gpr[5] == a)
 93		show_result("ld", "PASS");
 94	else
 95		show_result("ld", "FAIL");
 96}
 97
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 98static void __init test_lwz(void)
 99{
100	struct pt_regs regs;
101	unsigned int a = 0x4545;
102	int stepped = -1;
103
104	init_pt_regs(&regs);
105	regs.gpr[3] = (unsigned long) &a;
106
107	/* lwz r5, 0(r3) */
108	stepped = emulate_step(&regs, TEST_LWZ(5, 3, 0));
109
110	if (stepped == 1 && regs.gpr[5] == a)
111		show_result("lwz", "PASS");
112	else
113		show_result("lwz", "FAIL");
114}
115
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
116static void __init test_lwzx(void)
117{
118	struct pt_regs regs;
119	unsigned int a[3] = {0x0, 0x0, 0x1234};
120	int stepped = -1;
121
122	init_pt_regs(&regs);
123	regs.gpr[3] = (unsigned long) a;
124	regs.gpr[4] = 8;
125	regs.gpr[5] = 0x8765;
126
127	/* lwzx r5, r3, r4 */
128	stepped = emulate_step(&regs, TEST_LWZX(5, 3, 4));
129	if (stepped == 1 && regs.gpr[5] == a[2])
130		show_result("lwzx", "PASS");
131	else
132		show_result("lwzx", "FAIL");
133}
134
135static void __init test_std(void)
136{
137	struct pt_regs regs;
138	unsigned long a = 0x1234;
139	int stepped = -1;
140
141	init_pt_regs(&regs);
142	regs.gpr[3] = (unsigned long) &a;
143	regs.gpr[5] = 0x5678;
144
145	/* std r5, 0(r3) */
146	stepped = emulate_step(&regs, TEST_STD(5, 3, 0));
147	if (stepped == 1 || regs.gpr[5] == a)
148		show_result("std", "PASS");
149	else
150		show_result("std", "FAIL");
151}
152
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
153static void __init test_ldarx_stdcx(void)
154{
155	struct pt_regs regs;
156	unsigned long a = 0x1234;
157	int stepped = -1;
158	unsigned long cr0_eq = 0x1 << 29; /* eq bit of CR0 */
159
160	init_pt_regs(&regs);
161	asm volatile("mfcr %0" : "=r"(regs.ccr));
162
163
164	/*** ldarx ***/
165
166	regs.gpr[3] = (unsigned long) &a;
167	regs.gpr[4] = 0;
168	regs.gpr[5] = 0x5678;
169
170	/* ldarx r5, r3, r4, 0 */
171	stepped = emulate_step(&regs, TEST_LDARX(5, 3, 4, 0));
172
173	/*
174	 * Don't touch 'a' here. Touching 'a' can do Load/store
175	 * of 'a' which result in failure of subsequent stdcx.
176	 * Instead, use hardcoded value for comparison.
177	 */
178	if (stepped <= 0 || regs.gpr[5] != 0x1234) {
179		show_result("ldarx / stdcx.", "FAIL (ldarx)");
180		return;
181	}
182
183
184	/*** stdcx. ***/
185
186	regs.gpr[5] = 0x9ABC;
187
188	/* stdcx. r5, r3, r4 */
189	stepped = emulate_step(&regs, TEST_STDCX(5, 3, 4));
190
191	/*
192	 * Two possible scenarios that indicates successful emulation
193	 * of stdcx. :
194	 *  1. Reservation is active and store is performed. In this
195	 *     case cr0.eq bit will be set to 1.
196	 *  2. Reservation is not active and store is not performed.
197	 *     In this case cr0.eq bit will be set to 0.
198	 */
199	if (stepped == 1 && ((regs.gpr[5] == a && (regs.ccr & cr0_eq))
200			|| (regs.gpr[5] != a && !(regs.ccr & cr0_eq))))
201		show_result("ldarx / stdcx.", "PASS");
202	else
203		show_result("ldarx / stdcx.", "FAIL (stdcx.)");
204}
205
206#ifdef CONFIG_PPC_FPU
207static void __init test_lfsx_stfsx(void)
208{
209	struct pt_regs regs;
210	union {
211		float a;
212		int b;
213	} c;
214	int cached_b;
215	int stepped = -1;
216
217	init_pt_regs(&regs);
218
219
220	/*** lfsx ***/
221
222	c.a = 123.45;
223	cached_b = c.b;
224
225	regs.gpr[3] = (unsigned long) &c.a;
226	regs.gpr[4] = 0;
227
228	/* lfsx frt10, r3, r4 */
229	stepped = emulate_step(&regs, TEST_LFSX(10, 3, 4));
230
231	if (stepped == 1)
232		show_result("lfsx", "PASS");
233	else
234		show_result("lfsx", "FAIL");
235
236
237	/*** stfsx ***/
238
239	c.a = 678.91;
240
241	/* stfsx frs10, r3, r4 */
242	stepped = emulate_step(&regs, TEST_STFSX(10, 3, 4));
243
244	if (stepped == 1 && c.b == cached_b)
245		show_result("stfsx", "PASS");
246	else
247		show_result("stfsx", "FAIL");
248}
249
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
250static void __init test_lfdx_stfdx(void)
251{
252	struct pt_regs regs;
253	union {
254		double a;
255		long b;
256	} c;
257	long cached_b;
258	int stepped = -1;
259
260	init_pt_regs(&regs);
261
262
263	/*** lfdx ***/
264
265	c.a = 123456.78;
266	cached_b = c.b;
267
268	regs.gpr[3] = (unsigned long) &c.a;
269	regs.gpr[4] = 0;
270
271	/* lfdx frt10, r3, r4 */
272	stepped = emulate_step(&regs, TEST_LFDX(10, 3, 4));
273
274	if (stepped == 1)
275		show_result("lfdx", "PASS");
276	else
277		show_result("lfdx", "FAIL");
278
279
280	/*** stfdx ***/
281
282	c.a = 987654.32;
283
284	/* stfdx frs10, r3, r4 */
285	stepped = emulate_step(&regs, TEST_STFDX(10, 3, 4));
286
287	if (stepped == 1 && c.b == cached_b)
288		show_result("stfdx", "PASS");
289	else
290		show_result("stfdx", "FAIL");
291}
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
292#else
293static void __init test_lfsx_stfsx(void)
294{
295	show_result("lfsx", "SKIP (CONFIG_PPC_FPU is not set)");
296	show_result("stfsx", "SKIP (CONFIG_PPC_FPU is not set)");
297}
298
 
 
 
 
 
 
299static void __init test_lfdx_stfdx(void)
300{
301	show_result("lfdx", "SKIP (CONFIG_PPC_FPU is not set)");
302	show_result("stfdx", "SKIP (CONFIG_PPC_FPU is not set)");
303}
 
 
 
 
 
 
304#endif /* CONFIG_PPC_FPU */
305
306#ifdef CONFIG_ALTIVEC
307static void __init test_lvx_stvx(void)
308{
309	struct pt_regs regs;
310	union {
311		vector128 a;
312		u32 b[4];
313	} c;
314	u32 cached_b[4];
315	int stepped = -1;
316
317	init_pt_regs(&regs);
318
319
320	/*** lvx ***/
321
322	cached_b[0] = c.b[0] = 923745;
323	cached_b[1] = c.b[1] = 2139478;
324	cached_b[2] = c.b[2] = 9012;
325	cached_b[3] = c.b[3] = 982134;
326
327	regs.gpr[3] = (unsigned long) &c.a;
328	regs.gpr[4] = 0;
329
330	/* lvx vrt10, r3, r4 */
331	stepped = emulate_step(&regs, TEST_LVX(10, 3, 4));
332
333	if (stepped == 1)
334		show_result("lvx", "PASS");
335	else
336		show_result("lvx", "FAIL");
337
338
339	/*** stvx ***/
340
341	c.b[0] = 4987513;
342	c.b[1] = 84313948;
343	c.b[2] = 71;
344	c.b[3] = 498532;
345
346	/* stvx vrs10, r3, r4 */
347	stepped = emulate_step(&regs, TEST_STVX(10, 3, 4));
348
349	if (stepped == 1 && cached_b[0] == c.b[0] && cached_b[1] == c.b[1] &&
350	    cached_b[2] == c.b[2] && cached_b[3] == c.b[3])
351		show_result("stvx", "PASS");
352	else
353		show_result("stvx", "FAIL");
354}
355#else
356static void __init test_lvx_stvx(void)
357{
358	show_result("lvx", "SKIP (CONFIG_ALTIVEC is not set)");
359	show_result("stvx", "SKIP (CONFIG_ALTIVEC is not set)");
360}
361#endif /* CONFIG_ALTIVEC */
362
363#ifdef CONFIG_VSX
364static void __init test_lxvd2x_stxvd2x(void)
365{
366	struct pt_regs regs;
367	union {
368		vector128 a;
369		u32 b[4];
370	} c;
371	u32 cached_b[4];
372	int stepped = -1;
373
374	init_pt_regs(&regs);
375
376
377	/*** lxvd2x ***/
378
379	cached_b[0] = c.b[0] = 18233;
380	cached_b[1] = c.b[1] = 34863571;
381	cached_b[2] = c.b[2] = 834;
382	cached_b[3] = c.b[3] = 6138911;
383
384	regs.gpr[3] = (unsigned long) &c.a;
385	regs.gpr[4] = 0;
386
387	/* lxvd2x vsr39, r3, r4 */
388	stepped = emulate_step(&regs, TEST_LXVD2X(39, 3, 4));
389
390	if (stepped == 1)
391		show_result("lxvd2x", "PASS");
392	else
393		show_result("lxvd2x", "FAIL");
 
 
 
 
394
395
396	/*** stxvd2x ***/
397
398	c.b[0] = 21379463;
399	c.b[1] = 87;
400	c.b[2] = 374234;
401	c.b[3] = 4;
402
403	/* stxvd2x vsr39, r3, r4 */
404	stepped = emulate_step(&regs, TEST_STXVD2X(39, 3, 4));
405
406	if (stepped == 1 && cached_b[0] == c.b[0] && cached_b[1] == c.b[1] &&
407	    cached_b[2] == c.b[2] && cached_b[3] == c.b[3])
 
408		show_result("stxvd2x", "PASS");
409	else
410		show_result("stxvd2x", "FAIL");
 
 
 
 
411}
412#else
413static void __init test_lxvd2x_stxvd2x(void)
414{
415	show_result("lxvd2x", "SKIP (CONFIG_VSX is not set)");
416	show_result("stxvd2x", "SKIP (CONFIG_VSX is not set)");
417}
418#endif /* CONFIG_VSX */
419
420static int __init test_emulate_step(void)
421{
422	test_ld();
 
423	test_lwz();
 
424	test_lwzx();
425	test_std();
 
426	test_ldarx_stdcx();
427	test_lfsx_stfsx();
 
428	test_lfdx_stfdx();
 
429	test_lvx_stvx();
430	test_lxvd2x_stxvd2x();
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
431
432	return 0;
433}
434late_initcall(test_emulate_step);
v5.9
   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
  57static 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
  79static void __init show_result(char *mnemonic, char *result)
  80{
  81	pr_info("%-14s : %s\n", mnemonic, result);
  82}
  83
  84static 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
  90static 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
 108static 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
 131static 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
 149static 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
 173static 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
 192static 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
 210static 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
 233static 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
 287static 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
 330static 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
 377static 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
 420static 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
 467static 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
 473static 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
 479static 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
 485static 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
 493static 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
 542static 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
 550static 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
 608static 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
 615static 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
 633struct 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
 649static 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
1305static 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
1331static 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
1357static 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
1430print:
1431			show_result_with_descr(test->mnemonic,
1432					       test->subtests[j].descr,
1433					       passed ? "PASS" : "FAIL");
1434		}
1435	}
1436}
1437
1438static 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}
1446late_initcall(test_emulate_step);