1/*
2 * arch/s390/kernel/dis.c
3 *
4 * Disassemble s390 instructions.
5 *
6 * Copyright IBM Corp. 2007
7 * Author(s): Martin Schwidefsky (schwidefsky@de.ibm.com),
8 */
9
10#include <linux/sched.h>
11#include <linux/kernel.h>
12#include <linux/string.h>
13#include <linux/errno.h>
14#include <linux/ptrace.h>
15#include <linux/timer.h>
16#include <linux/mm.h>
17#include <linux/smp.h>
18#include <linux/smp_lock.h>
19#include <linux/init.h>
20#include <linux/interrupt.h>
21#include <linux/delay.h>
22#include <linux/module.h>
23#include <linux/kallsyms.h>
24#include <linux/reboot.h>
25#include <linux/kprobes.h>
26#include <linux/kdebug.h>
27
28#include <asm/system.h>
29#include <asm/uaccess.h>
30#include <asm/io.h>
31#include <asm/atomic.h>
32#include <asm/mathemu.h>
33#include <asm/cpcmd.h>
34#include <asm/s390_ext.h>
35#include <asm/lowcore.h>
36#include <asm/debug.h>
37
38#ifndef CONFIG_64BIT
39#define ONELONG "%08lx: "
40#else /* CONFIG_64BIT */
41#define ONELONG "%016lx: "
42#endif /* CONFIG_64BIT */
43
44#define OPERAND_GPR	0x1	/* Operand printed as %rx */
45#define OPERAND_FPR	0x2	/* Operand printed as %fx */
46#define OPERAND_AR	0x4	/* Operand printed as %ax */
47#define OPERAND_CR	0x8	/* Operand printed as %cx */
48#define OPERAND_DISP	0x10	/* Operand printed as displacement */
49#define OPERAND_BASE	0x20	/* Operand printed as base register */
50#define OPERAND_INDEX	0x40	/* Operand printed as index register */
51#define OPERAND_PCREL	0x80	/* Operand printed as pc-relative symbol */
52#define OPERAND_SIGNED	0x100	/* Operand printed as signed value */
53#define OPERAND_LENGTH	0x200	/* Operand printed as length (+1) */
54
55enum {
56	UNUSED,	/* Indicates the end of the operand list */
57	R_8,	/* GPR starting at position 8 */
58	R_12,	/* GPR starting at position 12 */
59	R_16,	/* GPR starting at position 16 */
60	R_20,	/* GPR starting at position 20 */
61	R_24,	/* GPR starting at position 24 */
62	R_28,	/* GPR starting at position 28 */
63	R_32,	/* GPR starting at position 32 */
64	F_8,	/* FPR starting at position 8 */
65	F_12,	/* FPR starting at position 12 */
66	F_16,	/* FPR starting at position 16 */
67	F_20,	/* FPR starting at position 16 */
68	F_24,	/* FPR starting at position 24 */
69	F_28,	/* FPR starting at position 28 */
70	F_32,	/* FPR starting at position 32 */
71	A_8,	/* Access reg. starting at position 8 */
72	A_12,	/* Access reg. starting at position 12 */
73	A_24,	/* Access reg. starting at position 24 */
74	A_28,	/* Access reg. starting at position 28 */
75	C_8,	/* Control reg. starting at position 8 */
76	C_12,	/* Control reg. starting at position 12 */
77	B_16,	/* Base register starting at position 16 */
78	B_32,	/* Base register starting at position 32 */
79	X_12,	/* Index register starting at position 12 */
80	D_20,	/* Displacement starting at position 20 */
81	D_36,	/* Displacement starting at position 36 */
82	D20_20,	/* 20 bit displacement starting at 20 */
83	L4_8,	/* 4 bit length starting at position 8 */
84	L4_12,	/* 4 bit length starting at position 12 */
85	L8_8,	/* 8 bit length starting at position 8 */
86	U4_8,	/* 4 bit unsigned value starting at 8 */
87	U4_12,	/* 4 bit unsigned value starting at 12 */
88	U4_16,	/* 4 bit unsigned value starting at 16 */
89	U4_20,	/* 4 bit unsigned value starting at 20 */
90	U8_8,	/* 8 bit unsigned value starting at 8 */
91	U8_16,	/* 8 bit unsigned value starting at 16 */
92	I16_16,	/* 16 bit signed value starting at 16 */
93	U16_16,	/* 16 bit unsigned value starting at 16 */
94	J16_16,	/* PC relative jump offset at 16 */
95	J32_16,	/* PC relative long offset at 16 */
96	I32_16,	/* 32 bit signed value starting at 16 */
97	U32_16,	/* 32 bit unsigned value starting at 16 */
98	M_16,	/* 4 bit optional mask starting at 16 */
99	RO_28,	/* optional GPR starting at position 28 */
100};
101
102/*
103 * Enumeration of the different instruction formats.
104 * For details consult the principles of operation.
105 */
106enum {
107	INSTR_INVALID,
108	INSTR_E, INSTR_RIE_RRP, INSTR_RIL_RI, INSTR_RIL_RP, INSTR_RIL_RU,
109	INSTR_RIL_UP, INSTR_RI_RI, INSTR_RI_RP, INSTR_RI_RU, INSTR_RI_UP,
110	INSTR_RRE_00, INSTR_RRE_0R, INSTR_RRE_AA, INSTR_RRE_AR, INSTR_RRE_F0,
111	INSTR_RRE_FF, INSTR_RRE_R0, INSTR_RRE_RA, INSTR_RRE_RF, INSTR_RRE_RR,
112	INSTR_RRE_RR_OPT, INSTR_RRF_F0FF, INSTR_RRF_FUFF, INSTR_RRF_M0RR,
113	INSTR_RRF_R0RR, INSTR_RRF_RURR, INSTR_RRF_U0FF, INSTR_RRF_U0RF,
114	INSTR_RR_FF, INSTR_RR_R0, INSTR_RR_RR, INSTR_RR_U0, INSTR_RR_UR,
115	INSTR_RSE_CCRD, INSTR_RSE_RRRD, INSTR_RSE_RURD, INSTR_RSI_RRP,
116	INSTR_RSL_R0RD, INSTR_RSY_AARD, INSTR_RSY_CCRD, INSTR_RSY_RRRD,
117	INSTR_RSY_RURD, INSTR_RS_AARD, INSTR_RS_CCRD, INSTR_RS_R0RD,
118	INSTR_RS_RRRD, INSTR_RS_RURD, INSTR_RXE_FRRD, INSTR_RXE_RRRD,
119	INSTR_RXF_FRRDF, INSTR_RXY_FRRD, INSTR_RXY_RRRD, INSTR_RX_FRRD,
120	INSTR_RX_RRRD, INSTR_RX_URRD, INSTR_SIY_URD, INSTR_SI_URD,
121	INSTR_SSE_RDRD, INSTR_SSF_RRDRD, INSTR_SS_L0RDRD, INSTR_SS_LIRDRD,
122	INSTR_SS_LLRDRD, INSTR_SS_RRRDRD, INSTR_SS_RRRDRD2, INSTR_SS_RRRDRD3,
123	INSTR_S_00, INSTR_S_RD,
124};
125
126struct operand {
127	int bits;		/* The number of bits in the operand. */
128	int shift;		/* The number of bits to shift. */
129	int flags;		/* One bit syntax flags. */
130};
131
132struct insn {
133	const char name[5];
134	unsigned char opfrag;
135	unsigned char format;
136};
137
138static const struct operand operands[] =
139{
140	[UNUSED]  = { 0, 0, 0 },
141	[R_8]	 = {  4,  8, OPERAND_GPR },
142	[R_12]	 = {  4, 12, OPERAND_GPR },
143	[R_16]	 = {  4, 16, OPERAND_GPR },
144	[R_20]	 = {  4, 20, OPERAND_GPR },
145	[R_24]	 = {  4, 24, OPERAND_GPR },
146	[R_28]	 = {  4, 28, OPERAND_GPR },
147	[R_32]	 = {  4, 32, OPERAND_GPR },
148	[F_8]	 = {  4,  8, OPERAND_FPR },
149	[F_12]	 = {  4, 12, OPERAND_FPR },
150	[F_16]	 = {  4, 16, OPERAND_FPR },
151	[F_20]	 = {  4, 16, OPERAND_FPR },
152	[F_24]	 = {  4, 24, OPERAND_FPR },
153	[F_28]	 = {  4, 28, OPERAND_FPR },
154	[F_32]	 = {  4, 32, OPERAND_FPR },
155	[A_8]	 = {  4,  8, OPERAND_AR },
156	[A_12]	 = {  4, 12, OPERAND_AR },
157	[A_24]	 = {  4, 24, OPERAND_AR },
158	[A_28]	 = {  4, 28, OPERAND_AR },
159	[C_8]	 = {  4,  8, OPERAND_CR },
160	[C_12]	 = {  4, 12, OPERAND_CR },
161	[B_16]	 = {  4, 16, OPERAND_BASE | OPERAND_GPR },
162	[B_32]	 = {  4, 32, OPERAND_BASE | OPERAND_GPR },
163	[X_12]	 = {  4, 12, OPERAND_INDEX | OPERAND_GPR },
164	[D_20]	 = { 12, 20, OPERAND_DISP },
165	[D_36]	 = { 12, 36, OPERAND_DISP },
166	[D20_20] = { 20, 20, OPERAND_DISP | OPERAND_SIGNED },
167	[L4_8]	 = {  4,  8, OPERAND_LENGTH },
168	[L4_12]  = {  4, 12, OPERAND_LENGTH },
169	[L8_8]	 = {  8,  8, OPERAND_LENGTH },
170	[U4_8]	 = {  4,  8, 0 },
171	[U4_12]  = {  4, 12, 0 },
172	[U4_16]  = {  4, 16, 0 },
173	[U4_20]  = {  4, 20, 0 },
174	[U8_8]	 = {  8,  8, 0 },
175	[U8_16]  = {  8, 16, 0 },
176	[I16_16] = { 16, 16, OPERAND_SIGNED },
177	[U16_16] = { 16, 16, 0 },
178	[J16_16] = { 16, 16, OPERAND_PCREL },
179	[J32_16] = { 32, 16, OPERAND_PCREL },
180	[I32_16] = { 32, 16, OPERAND_SIGNED },
181	[U32_16] = { 32, 16, 0 },
182	[M_16]	 = {  4, 16, 0 },
183	[RO_28]  = {  4, 28, OPERAND_GPR }
184};
185
186static const unsigned char formats[][7] = {
187	[INSTR_E]	  = { 0xff, 0,0,0,0,0,0 },	       /* e.g. pr    */
188	[INSTR_RIE_RRP]	  = { 0xff, R_8,R_12,J16_16,0,0,0 },   /* e.g. brxhg */
189	[INSTR_RIL_RP]	  = { 0x0f, R_8,J32_16,0,0,0,0 },      /* e.g. brasl */
190	[INSTR_RIL_UP]	  = { 0x0f, U4_8,J32_16,0,0,0,0 },     /* e.g. brcl  */
191	[INSTR_RIL_RI]	  = { 0x0f, R_8,I32_16,0,0,0,0 },      /* e.g. afi   */
192	[INSTR_RIL_RU]	  = { 0x0f, R_8,U32_16,0,0,0,0 },      /* e.g. alfi  */
193	[INSTR_RI_RI]	  = { 0x0f, R_8,I16_16,0,0,0,0 },      /* e.g. ahi   */
194	[INSTR_RI_RP]	  = { 0x0f, R_8,J16_16,0,0,0,0 },      /* e.g. brct  */
195	[INSTR_RI_RU]	  = { 0x0f, R_8,U16_16,0,0,0,0 },      /* e.g. tml   */
196	[INSTR_RI_UP]	  = { 0x0f, U4_8,J16_16,0,0,0,0 },     /* e.g. brc   */
197	[INSTR_RRE_00]	  = { 0xff, 0,0,0,0,0,0 },	       /* e.g. palb  */
198	[INSTR_RRE_0R]	  = { 0xff, R_28,0,0,0,0,0 },	       /* e.g. tb    */
199	[INSTR_RRE_AA]	  = { 0xff, A_24,A_28,0,0,0,0 },       /* e.g. cpya  */
200	[INSTR_RRE_AR]	  = { 0xff, A_24,R_28,0,0,0,0 },       /* e.g. sar   */
201	[INSTR_RRE_F0]	  = { 0xff, F_24,0,0,0,0,0 },	       /* e.g. sqer  */
202	[INSTR_RRE_FF]	  = { 0xff, F_24,F_28,0,0,0,0 },       /* e.g. debr  */
203	[INSTR_RRE_R0]	  = { 0xff, R_24,0,0,0,0,0 },	       /* e.g. ipm   */
204	[INSTR_RRE_RA]	  = { 0xff, R_24,A_28,0,0,0,0 },       /* e.g. ear   */
205	[INSTR_RRE_RF]	  = { 0xff, R_24,F_28,0,0,0,0 },       /* e.g. cefbr */
206	[INSTR_RRE_RR]	  = { 0xff, R_24,R_28,0,0,0,0 },       /* e.g. lura  */
207	[INSTR_RRE_RR_OPT]= { 0xff, R_24,RO_28,0,0,0,0 },      /* efpc, sfpc */
208	[INSTR_RRF_F0FF]  = { 0xff, F_16,F_24,F_28,0,0,0 },    /* e.g. madbr */
209	[INSTR_RRF_FUFF]  = { 0xff, F_24,F_16,F_28,U4_20,0,0 },/* e.g. didbr */
210	[INSTR_RRF_RURR]  = { 0xff, R_24,R_28,R_16,U4_20,0,0 },/* e.g. .insn */
211	[INSTR_RRF_R0RR]  = { 0xff, R_24,R_28,R_16,0,0,0 },    /* e.g. idte  */
212	[INSTR_RRF_U0FF]  = { 0xff, F_24,U4_16,F_28,0,0,0 },   /* e.g. fixr  */
213	[INSTR_RRF_U0RF]  = { 0xff, R_24,U4_16,F_28,0,0,0 },   /* e.g. cfebr */
214	[INSTR_RRF_M0RR]  = { 0xff, R_24,R_28,M_16,0,0,0 },    /* e.g. sske  */
215	[INSTR_RR_FF]	  = { 0xff, F_8,F_12,0,0,0,0 },        /* e.g. adr   */
216	[INSTR_RR_R0]	  = { 0xff, R_8, 0,0,0,0,0 },	       /* e.g. spm   */
217	[INSTR_RR_RR]	  = { 0xff, R_8,R_12,0,0,0,0 },        /* e.g. lr    */
218	[INSTR_RR_U0]	  = { 0xff, U8_8, 0,0,0,0,0 },	       /* e.g. svc   */
219	[INSTR_RR_UR]	  = { 0xff, U4_8,R_12,0,0,0,0 },       /* e.g. bcr   */
220	[INSTR_RSE_RRRD]  = { 0xff, R_8,R_12,D_20,B_16,0,0 },  /* e.g. lmh   */
221	[INSTR_RSE_CCRD]  = { 0xff, C_8,C_12,D_20,B_16,0,0 },  /* e.g. lmh   */
222	[INSTR_RSE_RURD]  = { 0xff, R_8,U4_12,D_20,B_16,0,0 }, /* e.g. icmh  */
223	[INSTR_RSL_R0RD]  = { 0xff, R_8,D_20,B_16,0,0,0 },     /* e.g. tp    */
224	[INSTR_RSI_RRP]	  = { 0xff, R_8,R_12,J16_16,0,0,0 },   /* e.g. brxh  */
225	[INSTR_RSY_RRRD]  = { 0xff, R_8,R_12,D20_20,B_16,0,0 },/* e.g. stmy  */
226	[INSTR_RSY_RURD]  = { 0xff, R_8,U4_12,D20_20,B_16,0,0 },
227							       /* e.g. icmh  */
228	[INSTR_RSY_AARD]  = { 0xff, A_8,A_12,D20_20,B_16,0,0 },/* e.g. lamy  */
229	[INSTR_RSY_CCRD]  = { 0xff, C_8,C_12,D20_20,B_16,0,0 },/* e.g. lamy  */
230	[INSTR_RS_AARD]	  = { 0xff, A_8,A_12,D_20,B_16,0,0 },  /* e.g. lam   */
231	[INSTR_RS_CCRD]	  = { 0xff, C_8,C_12,D_20,B_16,0,0 },  /* e.g. lctl  */
232	[INSTR_RS_R0RD]	  = { 0xff, R_8,D_20,B_16,0,0,0 },     /* e.g. sll   */
233	[INSTR_RS_RRRD]	  = { 0xff, R_8,R_12,D_20,B_16,0,0 },  /* e.g. cs    */
234	[INSTR_RS_RURD]	  = { 0xff, R_8,U4_12,D_20,B_16,0,0 }, /* e.g. icm   */
235	[INSTR_RXE_FRRD]  = { 0xff, F_8,D_20,X_12,B_16,0,0 },  /* e.g. axbr  */
236	[INSTR_RXE_RRRD]  = { 0xff, R_8,D_20,X_12,B_16,0,0 },  /* e.g. lg    */
237	[INSTR_RXF_FRRDF] = { 0xff, F_32,F_8,D_20,X_12,B_16,0 },
238							       /* e.g. madb  */
239	[INSTR_RXY_RRRD]  = { 0xff, R_8,D20_20,X_12,B_16,0,0 },/* e.g. ly    */
240	[INSTR_RXY_FRRD]  = { 0xff, F_8,D20_20,X_12,B_16,0,0 },/* e.g. ley   */
241	[INSTR_RX_FRRD]	  = { 0xff, F_8,D_20,X_12,B_16,0,0 },  /* e.g. ae    */
242	[INSTR_RX_RRRD]	  = { 0xff, R_8,D_20,X_12,B_16,0,0 },  /* e.g. l     */
243	[INSTR_RX_URRD]	  = { 0x00, U4_8,D_20,X_12,B_16,0,0 }, /* e.g. bc    */
244	[INSTR_SI_URD]	  = { 0x00, D_20,B_16,U8_8,0,0,0 },    /* e.g. cli   */
245	[INSTR_SIY_URD]	  = { 0xff, D20_20,B_16,U8_8,0,0,0 },  /* e.g. tmy   */
246	[INSTR_SSE_RDRD]  = { 0xff, D_20,B_16,D_36,B_32,0,0 }, /* e.g. mvsdk */
247	[INSTR_SS_L0RDRD] = { 0xff, D_20,L8_8,B_16,D_36,B_32,0 },
248							       /* e.g. mvc   */
249	[INSTR_SS_LIRDRD] = { 0xff, D_20,L4_8,B_16,D_36,B_32,U4_12 },
250							       /* e.g. srp   */
251	[INSTR_SS_LLRDRD] = { 0xff, D_20,L4_8,B_16,D_36,L4_12,B_32 },
252							       /* e.g. pack  */
253	[INSTR_SS_RRRDRD] = { 0xff, D_20,R_8,B_16,D_36,B_32,R_12 },
254							       /* e.g. mvck  */
255	[INSTR_SS_RRRDRD2]= { 0xff, R_8,D_20,B_16,R_12,D_36,B_32 },
256							       /* e.g. plo   */
257	[INSTR_SS_RRRDRD3]= { 0xff, R_8,R_12,D_20,B_16,D_36,B_32 },
258							       /* e.g. lmd   */
259	[INSTR_S_00]	  = { 0xff, 0,0,0,0,0,0 },	       /* e.g. hsch  */
260	[INSTR_S_RD]	  = { 0xff, D_20,B_16,0,0,0,0 },       /* e.g. lpsw  */
261	[INSTR_SSF_RRDRD] = { 0x00, D_20,B_16,D_36,B_32,R_8,0 },
262							       /* e.g. mvcos */
263};
264
265static struct insn opcode[] = {
266#ifdef CONFIG_64BIT
267	{ "lmd", 0xef, INSTR_SS_RRRDRD3 },
268#endif
269	{ "spm", 0x04, INSTR_RR_R0 },
270	{ "balr", 0x05, INSTR_RR_RR },
271	{ "bctr", 0x06, INSTR_RR_RR },
272	{ "bcr", 0x07, INSTR_RR_UR },
273	{ "svc", 0x0a, INSTR_RR_U0 },
274	{ "bsm", 0x0b, INSTR_RR_RR },
275	{ "bassm", 0x0c, INSTR_RR_RR },
276	{ "basr", 0x0d, INSTR_RR_RR },
277	{ "mvcl", 0x0e, INSTR_RR_RR },
278	{ "clcl", 0x0f, INSTR_RR_RR },
279	{ "lpr", 0x10, INSTR_RR_RR },
280	{ "lnr", 0x11, INSTR_RR_RR },
281	{ "ltr", 0x12, INSTR_RR_RR },
282	{ "lcr", 0x13, INSTR_RR_RR },
283	{ "nr", 0x14, INSTR_RR_RR },
284	{ "clr", 0x15, INSTR_RR_RR },
285	{ "or", 0x16, INSTR_RR_RR },
286	{ "xr", 0x17, INSTR_RR_RR },
287	{ "lr", 0x18, INSTR_RR_RR },
288	{ "cr", 0x19, INSTR_RR_RR },
289	{ "ar", 0x1a, INSTR_RR_RR },
290	{ "sr", 0x1b, INSTR_RR_RR },
291	{ "mr", 0x1c, INSTR_RR_RR },
292	{ "dr", 0x1d, INSTR_RR_RR },
293	{ "alr", 0x1e, INSTR_RR_RR },
294	{ "slr", 0x1f, INSTR_RR_RR },
295	{ "lpdr", 0x20, INSTR_RR_FF },
296	{ "lndr", 0x21, INSTR_RR_FF },
297	{ "ltdr", 0x22, INSTR_RR_FF },
298	{ "lcdr", 0x23, INSTR_RR_FF },
299	{ "hdr", 0x24, INSTR_RR_FF },
300	{ "ldxr", 0x25, INSTR_RR_FF },
301	{ "lrdr", 0x25, INSTR_RR_FF },
302	{ "mxr", 0x26, INSTR_RR_FF },
303	{ "mxdr", 0x27, INSTR_RR_FF },
304	{ "ldr", 0x28, INSTR_RR_FF },
305	{ "cdr", 0x29, INSTR_RR_FF },
306	{ "adr", 0x2a, INSTR_RR_FF },
307	{ "sdr", 0x2b, INSTR_RR_FF },
308	{ "mdr", 0x2c, INSTR_RR_FF },
309	{ "ddr", 0x2d, INSTR_RR_FF },
310	{ "awr", 0x2e, INSTR_RR_FF },
311	{ "swr", 0x2f, INSTR_RR_FF },
312	{ "lper", 0x30, INSTR_RR_FF },
313	{ "lner", 0x31, INSTR_RR_FF },
314	{ "lter", 0x32, INSTR_RR_FF },
315	{ "lcer", 0x33, INSTR_RR_FF },
316	{ "her", 0x34, INSTR_RR_FF },
317	{ "ledr", 0x35, INSTR_RR_FF },
318	{ "lrer", 0x35, INSTR_RR_FF },
319	{ "axr", 0x36, INSTR_RR_FF },
320	{ "sxr", 0x37, INSTR_RR_FF },
321	{ "ler", 0x38, INSTR_RR_FF },
322	{ "cer", 0x39, INSTR_RR_FF },
323	{ "aer", 0x3a, INSTR_RR_FF },
324	{ "ser", 0x3b, INSTR_RR_FF },
325	{ "mder", 0x3c, INSTR_RR_FF },
326	{ "mer", 0x3c, INSTR_RR_FF },
327	{ "der", 0x3d, INSTR_RR_FF },
328	{ "aur", 0x3e, INSTR_RR_FF },
329	{ "sur", 0x3f, INSTR_RR_FF },
330	{ "sth", 0x40, INSTR_RX_RRRD },
331	{ "la", 0x41, INSTR_RX_RRRD },
332	{ "stc", 0x42, INSTR_RX_RRRD },
333	{ "ic", 0x43, INSTR_RX_RRRD },
334	{ "ex", 0x44, INSTR_RX_RRRD },
335	{ "bal", 0x45, INSTR_RX_RRRD },
336	{ "bct", 0x46, INSTR_RX_RRRD },
337	{ "bc", 0x47, INSTR_RX_URRD },
338	{ "lh", 0x48, INSTR_RX_RRRD },
339	{ "ch", 0x49, INSTR_RX_RRRD },
340	{ "ah", 0x4a, INSTR_RX_RRRD },
341	{ "sh", 0x4b, INSTR_RX_RRRD },
342	{ "mh", 0x4c, INSTR_RX_RRRD },
343	{ "bas", 0x4d, INSTR_RX_RRRD },
344	{ "cvd", 0x4e, INSTR_RX_RRRD },
345	{ "cvb", 0x4f, INSTR_RX_RRRD },
346	{ "st", 0x50, INSTR_RX_RRRD },
347	{ "lae", 0x51, INSTR_RX_RRRD },
348	{ "n", 0x54, INSTR_RX_RRRD },
349	{ "cl", 0x55, INSTR_RX_RRRD },
350	{ "o", 0x56, INSTR_RX_RRRD },
351	{ "x", 0x57, INSTR_RX_RRRD },
352	{ "l", 0x58, INSTR_RX_RRRD },
353	{ "c", 0x59, INSTR_RX_RRRD },
354	{ "a", 0x5a, INSTR_RX_RRRD },
355	{ "s", 0x5b, INSTR_RX_RRRD },
356	{ "m", 0x5c, INSTR_RX_RRRD },
357	{ "d", 0x5d, INSTR_RX_RRRD },
358	{ "al", 0x5e, INSTR_RX_RRRD },
359	{ "sl", 0x5f, INSTR_RX_RRRD },
360	{ "std", 0x60, INSTR_RX_FRRD },
361	{ "mxd", 0x67, INSTR_RX_FRRD },
362	{ "ld", 0x68, INSTR_RX_FRRD },
363	{ "cd", 0x69, INSTR_RX_FRRD },
364	{ "ad", 0x6a, INSTR_RX_FRRD },
365	{ "sd", 0x6b, INSTR_RX_FRRD },
366	{ "md", 0x6c, INSTR_RX_FRRD },
367	{ "dd", 0x6d, INSTR_RX_FRRD },
368	{ "aw", 0x6e, INSTR_RX_FRRD },
369	{ "sw", 0x6f, INSTR_RX_FRRD },
370	{ "ste", 0x70, INSTR_RX_FRRD },
371	{ "ms", 0x71, INSTR_RX_RRRD },
372	{ "le", 0x78, INSTR_RX_FRRD },
373	{ "ce", 0x79, INSTR_RX_FRRD },
374	{ "ae", 0x7a, INSTR_RX_FRRD },
375	{ "se", 0x7b, INSTR_RX_FRRD },
376	{ "mde", 0x7c, INSTR_RX_FRRD },
377	{ "me", 0x7c, INSTR_RX_FRRD },
378	{ "de", 0x7d, INSTR_RX_FRRD },
379	{ "au", 0x7e, INSTR_RX_FRRD },
380	{ "su", 0x7f, INSTR_RX_FRRD },
381	{ "ssm", 0x80, INSTR_S_RD },
382	{ "lpsw", 0x82, INSTR_S_RD },
383	{ "diag", 0x83, INSTR_RS_RRRD },
384	{ "brxh", 0x84, INSTR_RSI_RRP },
385	{ "brxle", 0x85, INSTR_RSI_RRP },
386	{ "bxh", 0x86, INSTR_RS_RRRD },
387	{ "bxle", 0x87, INSTR_RS_RRRD },
388	{ "srl", 0x88, INSTR_RS_R0RD },
389	{ "sll", 0x89, INSTR_RS_R0RD },
390	{ "sra", 0x8a, INSTR_RS_R0RD },
391	{ "sla", 0x8b, INSTR_RS_R0RD },
392	{ "srdl", 0x8c, INSTR_RS_R0RD },
393	{ "sldl", 0x8d, INSTR_RS_R0RD },
394	{ "srda", 0x8e, INSTR_RS_R0RD },
395	{ "slda", 0x8f, INSTR_RS_R0RD },
396	{ "stm", 0x90, INSTR_RS_RRRD },
397	{ "tm", 0x91, INSTR_SI_URD },
398	{ "mvi", 0x92, INSTR_SI_URD },
399	{ "ts", 0x93, INSTR_S_RD },
400	{ "ni", 0x94, INSTR_SI_URD },
401	{ "cli", 0x95, INSTR_SI_URD },
402	{ "oi", 0x96, INSTR_SI_URD },
403	{ "xi", 0x97, INSTR_SI_URD },
404	{ "lm", 0x98, INSTR_RS_RRRD },
405	{ "trace", 0x99, INSTR_RS_RRRD },
406	{ "lam", 0x9a, INSTR_RS_AARD },
407	{ "stam", 0x9b, INSTR_RS_AARD },
408	{ "mvcle", 0xa8, INSTR_RS_RRRD },
409	{ "clcle", 0xa9, INSTR_RS_RRRD },
410	{ "stnsm", 0xac, INSTR_SI_URD },
411	{ "stosm", 0xad, INSTR_SI_URD },
412	{ "sigp", 0xae, INSTR_RS_RRRD },
413	{ "mc", 0xaf, INSTR_SI_URD },
414	{ "lra", 0xb1, INSTR_RX_RRRD },
415	{ "stctl", 0xb6, INSTR_RS_CCRD },
416	{ "lctl", 0xb7, INSTR_RS_CCRD },
417	{ "cs", 0xba, INSTR_RS_RRRD },
418	{ "cds", 0xbb, INSTR_RS_RRRD },
419	{ "clm", 0xbd, INSTR_RS_RURD },
420	{ "stcm", 0xbe, INSTR_RS_RURD },
421	{ "icm", 0xbf, INSTR_RS_RURD },
422	{ "mvn", 0xd1, INSTR_SS_L0RDRD },
423	{ "mvc", 0xd2, INSTR_SS_L0RDRD },
424	{ "mvz", 0xd3, INSTR_SS_L0RDRD },
425	{ "nc", 0xd4, INSTR_SS_L0RDRD },
426	{ "clc", 0xd5, INSTR_SS_L0RDRD },
427	{ "oc", 0xd6, INSTR_SS_L0RDRD },
428	{ "xc", 0xd7, INSTR_SS_L0RDRD },
429	{ "mvck", 0xd9, INSTR_SS_RRRDRD },
430	{ "mvcp", 0xda, INSTR_SS_RRRDRD },
431	{ "mvcs", 0xdb, INSTR_SS_RRRDRD },
432	{ "tr", 0xdc, INSTR_SS_L0RDRD },
433	{ "trt", 0xdd, INSTR_SS_L0RDRD },
434	{ "ed", 0xde, INSTR_SS_L0RDRD },
435	{ "edmk", 0xdf, INSTR_SS_L0RDRD },
436	{ "pku", 0xe1, INSTR_SS_L0RDRD },
437	{ "unpku", 0xe2, INSTR_SS_L0RDRD },
438	{ "mvcin", 0xe8, INSTR_SS_L0RDRD },
439	{ "pka", 0xe9, INSTR_SS_L0RDRD },
440	{ "unpka", 0xea, INSTR_SS_L0RDRD },
441	{ "plo", 0xee, INSTR_SS_RRRDRD2 },
442	{ "srp", 0xf0, INSTR_SS_LIRDRD },
443	{ "mvo", 0xf1, INSTR_SS_LLRDRD },
444	{ "pack", 0xf2, INSTR_SS_LLRDRD },
445	{ "unpk", 0xf3, INSTR_SS_LLRDRD },
446	{ "zap", 0xf8, INSTR_SS_LLRDRD },
447	{ "cp", 0xf9, INSTR_SS_LLRDRD },
448	{ "ap", 0xfa, INSTR_SS_LLRDRD },
449	{ "sp", 0xfb, INSTR_SS_LLRDRD },
450	{ "mp", 0xfc, INSTR_SS_LLRDRD },
451	{ "dp", 0xfd, INSTR_SS_LLRDRD },
452	{ "", 0, INSTR_INVALID }
453};
454
455static struct insn opcode_01[] = {
456#ifdef CONFIG_64BIT
457	{ "sam64", 0x0e, INSTR_E },
458#endif
459	{ "pr", 0x01, INSTR_E },
460	{ "upt", 0x02, INSTR_E },
461	{ "sckpf", 0x07, INSTR_E },
462	{ "tam", 0x0b, INSTR_E },
463	{ "sam24", 0x0c, INSTR_E },
464	{ "sam31", 0x0d, INSTR_E },
465	{ "trap2", 0xff, INSTR_E },
466	{ "", 0, INSTR_INVALID }
467};
468
469static struct insn opcode_a5[] = {
470#ifdef CONFIG_64BIT
471	{ "iihh", 0x00, INSTR_RI_RU },
472	{ "iihl", 0x01, INSTR_RI_RU },
473	{ "iilh", 0x02, INSTR_RI_RU },
474	{ "iill", 0x03, INSTR_RI_RU },
475	{ "nihh", 0x04, INSTR_RI_RU },
476	{ "nihl", 0x05, INSTR_RI_RU },
477	{ "nilh", 0x06, INSTR_RI_RU },
478	{ "nill", 0x07, INSTR_RI_RU },
479	{ "oihh", 0x08, INSTR_RI_RU },
480	{ "oihl", 0x09, INSTR_RI_RU },
481	{ "oilh", 0x0a, INSTR_RI_RU },
482	{ "oill", 0x0b, INSTR_RI_RU },
483	{ "llihh", 0x0c, INSTR_RI_RU },
484	{ "llihl", 0x0d, INSTR_RI_RU },
485	{ "llilh", 0x0e, INSTR_RI_RU },
486	{ "llill", 0x0f, INSTR_RI_RU },
487#endif
488	{ "", 0, INSTR_INVALID }
489};
490
491static struct insn opcode_a7[] = {
492#ifdef CONFIG_64BIT
493	{ "tmhh", 0x02, INSTR_RI_RU },
494	{ "tmhl", 0x03, INSTR_RI_RU },
495	{ "brctg", 0x07, INSTR_RI_RP },
496	{ "lghi", 0x09, INSTR_RI_RI },
497	{ "aghi", 0x0b, INSTR_RI_RI },
498	{ "mghi", 0x0d, INSTR_RI_RI },
499	{ "cghi", 0x0f, INSTR_RI_RI },
500#endif
501	{ "tmlh", 0x00, INSTR_RI_RU },
502	{ "tmll", 0x01, INSTR_RI_RU },
503	{ "brc", 0x04, INSTR_RI_UP },
504	{ "bras", 0x05, INSTR_RI_RP },
505	{ "brct", 0x06, INSTR_RI_RP },
506	{ "lhi", 0x08, INSTR_RI_RI },
507	{ "ahi", 0x0a, INSTR_RI_RI },
508	{ "mhi", 0x0c, INSTR_RI_RI },
509	{ "chi", 0x0e, INSTR_RI_RI },
510	{ "", 0, INSTR_INVALID }
511};
512
513static struct insn opcode_b2[] = {
514#ifdef CONFIG_64BIT
515	{ "sske", 0x2b, INSTR_RRF_M0RR },
516	{ "stckf", 0x7c, INSTR_S_RD },
517	{ "cu21", 0xa6, INSTR_RRF_M0RR },
518	{ "cuutf", 0xa6, INSTR_RRF_M0RR },
519	{ "cu12", 0xa7, INSTR_RRF_M0RR },
520	{ "cutfu", 0xa7, INSTR_RRF_M0RR },
521	{ "stfle", 0xb0, INSTR_S_RD },
522	{ "lpswe", 0xb2, INSTR_S_RD },
523#endif
524	{ "stidp", 0x02, INSTR_S_RD },
525	{ "sck", 0x04, INSTR_S_RD },
526	{ "stck", 0x05, INSTR_S_RD },
527	{ "sckc", 0x06, INSTR_S_RD },
528	{ "stckc", 0x07, INSTR_S_RD },
529	{ "spt", 0x08, INSTR_S_RD },
530	{ "stpt", 0x09, INSTR_S_RD },
531	{ "spka", 0x0a, INSTR_S_RD },
532	{ "ipk", 0x0b, INSTR_S_00 },
533	{ "ptlb", 0x0d, INSTR_S_00 },
534	{ "spx", 0x10, INSTR_S_RD },
535	{ "stpx", 0x11, INSTR_S_RD },
536	{ "stap", 0x12, INSTR_S_RD },
537	{ "sie", 0x14, INSTR_S_RD },
538	{ "pc", 0x18, INSTR_S_RD },
539	{ "sac", 0x19, INSTR_S_RD },
540	{ "cfc", 0x1a, INSTR_S_RD },
541	{ "ipte", 0x21, INSTR_RRE_RR },
542	{ "ipm", 0x22, INSTR_RRE_R0 },
543	{ "ivsk", 0x23, INSTR_RRE_RR },
544	{ "iac", 0x24, INSTR_RRE_R0 },
545	{ "ssar", 0x25, INSTR_RRE_R0 },
546	{ "epar", 0x26, INSTR_RRE_R0 },
547	{ "esar", 0x27, INSTR_RRE_R0 },
548	{ "pt", 0x28, INSTR_RRE_RR },
549	{ "iske", 0x29, INSTR_RRE_RR },
550	{ "rrbe", 0x2a, INSTR_RRE_RR },
551	{ "sske", 0x2b, INSTR_RRE_RR },
552	{ "tb", 0x2c, INSTR_RRE_0R },
553	{ "dxr", 0x2d, INSTR_RRE_F0 },
554	{ "pgin", 0x2e, INSTR_RRE_RR },
555	{ "pgout", 0x2f, INSTR_RRE_RR },
556	{ "csch", 0x30, INSTR_S_00 },
557	{ "hsch", 0x31, INSTR_S_00 },
558	{ "msch", 0x32, INSTR_S_RD },
559	{ "ssch", 0x33, INSTR_S_RD },
560	{ "stsch", 0x34, INSTR_S_RD },
561	{ "tsch", 0x35, INSTR_S_RD },
562	{ "tpi", 0x36, INSTR_S_RD },
563	{ "sal", 0x37, INSTR_S_00 },
564	{ "rsch", 0x38, INSTR_S_00 },
565	{ "stcrw", 0x39, INSTR_S_RD },
566	{ "stcps", 0x3a, INSTR_S_RD },
567	{ "rchp", 0x3b, INSTR_S_00 },
568	{ "schm", 0x3c, INSTR_S_00 },
569	{ "bakr", 0x40, INSTR_RRE_RR },
570	{ "cksm", 0x41, INSTR_RRE_RR },
571	{ "sqdr", 0x44, INSTR_RRE_F0 },
572	{ "sqer", 0x45, INSTR_RRE_F0 },
573	{ "stura", 0x46, INSTR_RRE_RR },
574	{ "msta", 0x47, INSTR_RRE_R0 },
575	{ "palb", 0x48, INSTR_RRE_00 },
576	{ "ereg", 0x49, INSTR_RRE_RR },
577	{ "esta", 0x4a, INSTR_RRE_RR },
578	{ "lura", 0x4b, INSTR_RRE_RR },
579	{ "tar", 0x4c, INSTR_RRE_AR },
580	{ "cpya", INSTR_RRE_AA },
581	{ "sar", 0x4e, INSTR_RRE_AR },
582	{ "ear", 0x4f, INSTR_RRE_RA },
583	{ "csp", 0x50, INSTR_RRE_RR },
584	{ "msr", 0x52, INSTR_RRE_RR },
585	{ "mvpg", 0x54, INSTR_RRE_RR },
586	{ "mvst", 0x55, INSTR_RRE_RR },
587	{ "cuse", 0x57, INSTR_RRE_RR },
588	{ "bsg", 0x58, INSTR_RRE_RR },
589	{ "bsa", 0x5a, INSTR_RRE_RR },
590	{ "clst", 0x5d, INSTR_RRE_RR },
591	{ "srst", 0x5e, INSTR_RRE_RR },
592	{ "cmpsc", 0x63, INSTR_RRE_RR },
593	{ "cmpsc", 0x63, INSTR_RRE_RR },
594	{ "siga", 0x74, INSTR_S_RD },
595	{ "xsch", 0x76, INSTR_S_00 },
596	{ "rp", 0x77, INSTR_S_RD },
597	{ "stcke", 0x78, INSTR_S_RD },
598	{ "sacf", 0x79, INSTR_S_RD },
599	{ "stsi", 0x7d, INSTR_S_RD },
600	{ "srnm", 0x99, INSTR_S_RD },
601	{ "stfpc", 0x9c, INSTR_S_RD },
602	{ "lfpc", 0x9d, INSTR_S_RD },
603	{ "tre", 0xa5, INSTR_RRE_RR },
604	{ "cuutf", 0xa6, INSTR_RRE_RR },
605	{ "cutfu", 0xa7, INSTR_RRE_RR },
606	{ "stfl", 0xb1, INSTR_S_RD },
607	{ "trap4", 0xff, INSTR_S_RD },
608	{ "", 0, INSTR_INVALID }
609};
610
611static struct insn opcode_b3[] = {
612#ifdef CONFIG_64BIT
613	{ "maylr", 0x38, INSTR_RRF_F0FF },
614	{ "mylr", 0x39, INSTR_RRF_F0FF },
615	{ "mayr", 0x3a, INSTR_RRF_F0FF },
616	{ "myr", 0x3b, INSTR_RRF_F0FF },
617	{ "mayhr", 0x3c, INSTR_RRF_F0FF },
618	{ "myhr", 0x3d, INSTR_RRF_F0FF },
619	{ "cegbr", 0xa4, INSTR_RRE_RR },
620	{ "cdgbr", 0xa5, INSTR_RRE_RR },
621	{ "cxgbr", 0xa6, INSTR_RRE_RR },
622	{ "cgebr", 0xa8, INSTR_RRF_U0RF },
623	{ "cgdbr", 0xa9, INSTR_RRF_U0RF },
624	{ "cgxbr", 0xaa, INSTR_RRF_U0RF },
625	{ "cfer", 0xb8, INSTR_RRF_U0RF },
626	{ "cfdr", 0xb9, INSTR_RRF_U0RF },
627	{ "cfxr", 0xba, INSTR_RRF_U0RF },
628	{ "cegr", 0xc4, INSTR_RRE_RR },
629	{ "cdgr", 0xc5, INSTR_RRE_RR },
630	{ "cxgr", 0xc6, INSTR_RRE_RR },
631	{ "cger", 0xc8, INSTR_RRF_U0RF },
632	{ "cgdr", 0xc9, INSTR_RRF_U0RF },
633	{ "cgxr", 0xca, INSTR_RRF_U0RF },
634#endif
635	{ "lpebr", 0x00, INSTR_RRE_FF },
636	{ "lnebr", 0x01, INSTR_RRE_FF },
637	{ "ltebr", 0x02, INSTR_RRE_FF },
638	{ "lcebr", 0x03, INSTR_RRE_FF },
639	{ "ldebr", 0x04, INSTR_RRE_FF },
640	{ "lxdbr", 0x05, INSTR_RRE_FF },
641	{ "lxebr", 0x06, INSTR_RRE_FF },
642	{ "mxdbr", 0x07, INSTR_RRE_FF },
643	{ "kebr", 0x08, INSTR_RRE_FF },
644	{ "cebr", 0x09, INSTR_RRE_FF },
645	{ "aebr", 0x0a, INSTR_RRE_FF },
646	{ "sebr", 0x0b, INSTR_RRE_FF },
647	{ "mdebr", 0x0c, INSTR_RRE_FF },
648	{ "debr", 0x0d, INSTR_RRE_FF },
649	{ "maebr", 0x0e, INSTR_RRF_F0FF },
650	{ "msebr", 0x0f, INSTR_RRF_F0FF },
651	{ "lpdbr", 0x10, INSTR_RRE_FF },
652	{ "lndbr", 0x11, INSTR_RRE_FF },
653	{ "ltdbr", 0x12, INSTR_RRE_FF },
654	{ "lcdbr", 0x13, INSTR_RRE_FF },
655	{ "sqebr", 0x14, INSTR_RRE_FF },
656	{ "sqdbr", 0x15, INSTR_RRE_FF },
657	{ "sqxbr", 0x16, INSTR_RRE_FF },
658	{ "meebr", 0x17, INSTR_RRE_FF },
659	{ "kdbr", 0x18, INSTR_RRE_FF },
660	{ "cdbr", 0x19, INSTR_RRE_FF },
661	{ "adbr", 0x1a, INSTR_RRE_FF },
662	{ "sdbr", 0x1b, INSTR_RRE_FF },
663	{ "mdbr", 0x1c, INSTR_RRE_FF },
664	{ "ddbr", 0x1d, INSTR_RRE_FF },
665	{ "madbr", 0x1e, INSTR_RRF_F0FF },
666	{ "msdbr", 0x1f, INSTR_RRF_F0FF },
667	{ "lder", 0x24, INSTR_RRE_FF },
668	{ "lxdr", 0x25, INSTR_RRE_FF },
669	{ "lxer", 0x26, INSTR_RRE_FF },
670	{ "maer", 0x2e, INSTR_RRF_F0FF },
671	{ "mser", 0x2f, INSTR_RRF_F0FF },
672	{ "sqxr", 0x36, INSTR_RRE_FF },
673	{ "meer", 0x37, INSTR_RRE_FF },
674	{ "madr", 0x3e, INSTR_RRF_F0FF },
675	{ "msdr", 0x3f, INSTR_RRF_F0FF },
676	{ "lpxbr", 0x40, INSTR_RRE_FF },
677	{ "lnxbr", 0x41, INSTR_RRE_FF },
678	{ "ltxbr", 0x42, INSTR_RRE_FF },
679	{ "lcxbr", 0x43, INSTR_RRE_FF },
680	{ "ledbr", 0x44, INSTR_RRE_FF },
681	{ "ldxbr", 0x45, INSTR_RRE_FF },
682	{ "lexbr", 0x46, INSTR_RRE_FF },
683	{ "fixbr", 0x47, INSTR_RRF_U0FF },
684	{ "kxbr", 0x48, INSTR_RRE_FF },
685	{ "cxbr", 0x49, INSTR_RRE_FF },
686	{ "axbr", 0x4a, INSTR_RRE_FF },
687	{ "sxbr", 0x4b, INSTR_RRE_FF },
688	{ "mxbr", 0x4c, INSTR_RRE_FF },
689	{ "dxbr", 0x4d, INSTR_RRE_FF },
690	{ "tbedr", 0x50, INSTR_RRF_U0FF },
691	{ "tbdr", 0x51, INSTR_RRF_U0FF },
692	{ "diebr", 0x53, INSTR_RRF_FUFF },
693	{ "fiebr", 0x57, INSTR_RRF_U0FF },
694	{ "thder", 0x58, INSTR_RRE_RR },
695	{ "thdr", 0x59, INSTR_RRE_RR },
696	{ "didbr", 0x5b, INSTR_RRF_FUFF },
697	{ "fidbr", 0x5f, INSTR_RRF_U0FF },
698	{ "lpxr", 0x60, INSTR_RRE_FF },
699	{ "lnxr", 0x61, INSTR_RRE_FF },
700	{ "ltxr", 0x62, INSTR_RRE_FF },
701	{ "lcxr", 0x63, INSTR_RRE_FF },
702	{ "lxr", 0x65, INSTR_RRE_RR },
703	{ "lexr", 0x66, INSTR_RRE_FF },
704	{ "fixr", 0x67, INSTR_RRF_U0FF },
705	{ "cxr", 0x69, INSTR_RRE_FF },
706	{ "lzer", 0x74, INSTR_RRE_R0 },
707	{ "lzdr", 0x75, INSTR_RRE_R0 },
708	{ "lzxr", 0x76, INSTR_RRE_R0 },
709	{ "fier", 0x77, INSTR_RRF_U0FF },
710	{ "fidr", 0x7f, INSTR_RRF_U0FF },
711	{ "sfpc", 0x84, INSTR_RRE_RR_OPT },
712	{ "efpc", 0x8c, INSTR_RRE_RR_OPT },
713	{ "cefbr", 0x94, INSTR_RRE_RF },
714	{ "cdfbr", 0x95, INSTR_RRE_RF },
715	{ "cxfbr", 0x96, INSTR_RRE_RF },
716	{ "cfebr", 0x98, INSTR_RRF_U0RF },
717	{ "cfdbr", 0x99, INSTR_RRF_U0RF },
718	{ "cfxbr", 0x9a, INSTR_RRF_U0RF },
719	{ "cefr", 0xb4, INSTR_RRE_RF },
720	{ "cdfr", 0xb5, INSTR_RRE_RF },
721	{ "cxfr", 0xb6, INSTR_RRE_RF },
722	{ "", 0, INSTR_INVALID }
723};
724
725static struct insn opcode_b9[] = {
726#ifdef CONFIG_64BIT
727	{ "lpgr", 0x00, INSTR_RRE_RR },
728	{ "lngr", 0x01, INSTR_RRE_RR },
729	{ "ltgr", 0x02, INSTR_RRE_RR },
730	{ "lcgr", 0x03, INSTR_RRE_RR },
731	{ "lgr", 0x04, INSTR_RRE_RR },
732	{ "lurag", 0x05, INSTR_RRE_RR },
733	{ "lgbr", 0x06, INSTR_RRE_RR },
734	{ "lghr", 0x07, INSTR_RRE_RR },
735	{ "agr", 0x08, INSTR_RRE_RR },
736	{ "sgr", 0x09, INSTR_RRE_RR },
737	{ "algr", 0x0a, INSTR_RRE_RR },
738	{ "slgr", 0x0b, INSTR_RRE_RR },
739	{ "msgr", 0x0c, INSTR_RRE_RR },
740	{ "dsgr", 0x0d, INSTR_RRE_RR },
741	{ "eregg", 0x0e, INSTR_RRE_RR },
742	{ "lrvgr", 0x0f, INSTR_RRE_RR },
743	{ "lpgfr", 0x10, INSTR_RRE_RR },
744	{ "lngfr", 0x11, INSTR_RRE_RR },
745	{ "ltgfr", 0x12, INSTR_RRE_RR },
746	{ "lcgfr", 0x13, INSTR_RRE_RR },
747	{ "lgfr", 0x14, INSTR_RRE_RR },
748	{ "llgfr", 0x16, INSTR_RRE_RR },
749	{ "llgtr", 0x17, INSTR_RRE_RR },
750	{ "agfr", 0x18, INSTR_RRE_RR },
751	{ "sgfr", 0x19, INSTR_RRE_RR },
752	{ "algfr", 0x1a, INSTR_RRE_RR },
753	{ "slgfr", 0x1b, INSTR_RRE_RR },
754	{ "msgfr", 0x1c, INSTR_RRE_RR },
755	{ "dsgfr", 0x1d, INSTR_RRE_RR },
756	{ "cgr", 0x20, INSTR_RRE_RR },
757	{ "clgr", 0x21, INSTR_RRE_RR },
758	{ "sturg", 0x25, INSTR_RRE_RR },
759	{ "lbr", 0x26, INSTR_RRE_RR },
760	{ "lhr", 0x27, INSTR_RRE_RR },
761	{ "cgfr", 0x30, INSTR_RRE_RR },
762	{ "clgfr", 0x31, INSTR_RRE_RR },
763	{ "bctgr", 0x46, INSTR_RRE_RR },
764	{ "ngr", 0x80, INSTR_RRE_RR },
765	{ "ogr", 0x81, INSTR_RRE_RR },
766	{ "xgr", 0x82, INSTR_RRE_RR },
767	{ "flogr", 0x83, INSTR_RRE_RR },
768	{ "llgcr", 0x84, INSTR_RRE_RR },
769	{ "llghr", 0x85, INSTR_RRE_RR },
770	{ "mlgr", 0x86, INSTR_RRE_RR },
771	{ "dlgr", 0x87, INSTR_RRE_RR },
772	{ "alcgr", 0x88, INSTR_RRE_RR },
773	{ "slbgr", 0x89, INSTR_RRE_RR },
774	{ "cspg", 0x8a, INSTR_RRE_RR },
775	{ "idte", 0x8e, INSTR_RRF_R0RR },
776	{ "llcr", 0x94, INSTR_RRE_RR },
777	{ "llhr", 0x95, INSTR_RRE_RR },
778	{ "esea", 0x9d, INSTR_RRE_R0 },
779	{ "lptea", 0xaa, INSTR_RRF_RURR },
780	{ "cu14", 0xb0, INSTR_RRF_M0RR },
781	{ "cu24", 0xb1, INSTR_RRF_M0RR },
782	{ "cu41", 0xb2, INSTR_RRF_M0RR },
783	{ "cu42", 0xb3, INSTR_RRF_M0RR },
784#endif
785	{ "kmac", 0x1e, INSTR_RRE_RR },
786	{ "lrvr", 0x1f, INSTR_RRE_RR },
787	{ "km", 0x2e, INSTR_RRE_RR },
788	{ "kmc", 0x2f, INSTR_RRE_RR },
789	{ "kimd", 0x3e, INSTR_RRE_RR },
790	{ "klmd", 0x3f, INSTR_RRE_RR },
791	{ "epsw", 0x8d, INSTR_RRE_RR },
792	{ "trtt", 0x90, INSTR_RRE_RR },
793	{ "trtt", 0x90, INSTR_RRF_M0RR },
794	{ "trto", 0x91, INSTR_RRE_RR },
795	{ "trto", 0x91, INSTR_RRF_M0RR },
796	{ "trot", 0x92, INSTR_RRE_RR },
797	{ "trot", 0x92, INSTR_RRF_M0RR },
798	{ "troo", 0x93, INSTR_RRE_RR },
799	{ "troo", 0x93, INSTR_RRF_M0RR },
800	{ "mlr", 0x96, INSTR_RRE_RR },
801	{ "dlr", 0x97, INSTR_RRE_RR },
802	{ "alcr", 0x98, INSTR_RRE_RR },
803	{ "slbr", 0x99, INSTR_RRE_RR },
804	{ "", 0, INSTR_INVALID }
805};
806
807static struct insn opcode_c0[] = {
808#ifdef CONFIG_64BIT
809	{ "lgfi", 0x01, INSTR_RIL_RI },
810	{ "xihf", 0x06, INSTR_RIL_RU },
811	{ "xilf", 0x07, INSTR_RIL_RU },
812	{ "iihf", 0x08, INSTR_RIL_RU },
813	{ "iilf", 0x09, INSTR_RIL_RU },
814	{ "nihf", 0x0a, INSTR_RIL_RU },
815	{ "nilf", 0x0b, INSTR_RIL_RU },
816	{ "oihf", 0x0c, INSTR_RIL_RU },
817	{ "oilf", 0x0d, INSTR_RIL_RU },
818	{ "llihf", 0x0e, INSTR_RIL_RU },
819	{ "llilf", 0x0f, INSTR_RIL_RU },
820#endif
821	{ "larl", 0x00, INSTR_RIL_RP },
822	{ "brcl", 0x04, INSTR_RIL_UP },
823	{ "brasl", 0x05, INSTR_RIL_RP },
824	{ "", 0, INSTR_INVALID }
825};
826
827static struct insn opcode_c2[] = {
828#ifdef CONFIG_64BIT
829	{ "slgfi", 0x04, INSTR_RIL_RU },
830	{ "slfi", 0x05, INSTR_RIL_RU },
831	{ "agfi", 0x08, INSTR_RIL_RI },
832	{ "afi", 0x09, INSTR_RIL_RI },
833	{ "algfi", 0x0a, INSTR_RIL_RU },
834	{ "alfi", 0x0b, INSTR_RIL_RU },
835	{ "cgfi", 0x0c, INSTR_RIL_RI },
836	{ "cfi", 0x0d, INSTR_RIL_RI },
837	{ "clgfi", 0x0e, INSTR_RIL_RU },
838	{ "clfi", 0x0f, INSTR_RIL_RU },
839#endif
840	{ "", 0, INSTR_INVALID }
841};
842
843static struct insn opcode_c8[] = {
844#ifdef CONFIG_64BIT
845	{ "mvcos", 0x00, INSTR_SSF_RRDRD },
846#endif
847	{ "", 0, INSTR_INVALID }
848};
849
850static struct insn opcode_e3[] = {
851#ifdef CONFIG_64BIT
852	{ "ltg", 0x02, INSTR_RXY_RRRD },
853	{ "lrag", 0x03, INSTR_RXY_RRRD },
854	{ "lg", 0x04, INSTR_RXY_RRRD },
855	{ "cvby", 0x06, INSTR_RXY_RRRD },
856	{ "ag", 0x08, INSTR_RXY_RRRD },
857	{ "sg", 0x09, INSTR_RXY_RRRD },
858	{ "alg", 0x0a, INSTR_RXY_RRRD },
859	{ "slg", 0x0b, INSTR_RXY_RRRD },
860	{ "msg", 0x0c, INSTR_RXY_RRRD },
861	{ "dsg", 0x0d, INSTR_RXY_RRRD },
862	{ "cvbg", 0x0e, INSTR_RXY_RRRD },
863	{ "lrvg", 0x0f, INSTR_RXY_RRRD },
864	{ "lt", 0x12, INSTR_RXY_RRRD },
865	{ "lray", 0x13, INSTR_RXY_RRRD },
866	{ "lgf", 0x14, INSTR_RXY_RRRD },
867	{ "lgh", 0x15, INSTR_RXY_RRRD },
868	{ "llgf", 0x16, INSTR_RXY_RRRD },
869	{ "llgt", 0x17, INSTR_RXY_RRRD },
870	{ "agf", 0x18, INSTR_RXY_RRRD },
871	{ "sgf", 0x19, INSTR_RXY_RRRD },
872	{ "algf", 0x1a, INSTR_RXY_RRRD },
873	{ "slgf", 0x1b, INSTR_RXY_RRRD },
874	{ "msgf", 0x1c, INSTR_RXY_RRRD },
875	{ "dsgf", 0x1d, INSTR_RXY_RRRD },
876	{ "cg", 0x20, INSTR_RXY_RRRD },
877	{ "clg", 0x21, INSTR_RXY_RRRD },
878	{ "stg", 0x24, INSTR_RXY_RRRD },
879	{ "cvdy", 0x26, INSTR_RXY_RRRD },
880	{ "cvdg", 0x2e, INSTR_RXY_RRRD },
881	{ "strvg", 0x2f, INSTR_RXY_RRRD },
882	{ "cgf", 0x30, INSTR_RXY_RRRD },
883	{ "clgf", 0x31, INSTR_RXY_RRRD },
884	{ "strvh", 0x3f, INSTR_RXY_RRRD },
885	{ "bctg", 0x46, INSTR_RXY_RRRD },
886	{ "sty", 0x50, INSTR_RXY_RRRD },
887	{ "msy", 0x51, INSTR_RXY_RRRD },
888	{ "ny", 0x54, INSTR_RXY_RRRD },
889	{ "cly", 0x55, INSTR_RXY_RRRD },
890	{ "oy", 0x56, INSTR_RXY_RRRD },
891	{ "xy", 0x57, INSTR_RXY_RRRD },
892	{ "ly", 0x58, INSTR_RXY_RRRD },
893	{ "cy", 0x59, INSTR_RXY_RRRD },
894	{ "ay", 0x5a, INSTR_RXY_RRRD },
895	{ "sy", 0x5b, INSTR_RXY_RRRD },
896	{ "aly", 0x5e, INSTR_RXY_RRRD },
897	{ "sly", 0x5f, INSTR_RXY_RRRD },
898	{ "sthy", 0x70, INSTR_RXY_RRRD },
899	{ "lay", 0x71, INSTR_RXY_RRRD },
900	{ "stcy", 0x72, INSTR_RXY_RRRD },
901	{ "icy", 0x73, INSTR_RXY_RRRD },
902	{ "lb", 0x76, INSTR_RXY_RRRD },
903	{ "lgb", 0x77, INSTR_RXY_RRRD },
904	{ "lhy", 0x78, INSTR_RXY_RRRD },
905	{ "chy", 0x79, INSTR_RXY_RRRD },
906	{ "ahy", 0x7a, INSTR_RXY_RRRD },
907	{ "shy", 0x7b, INSTR_RXY_RRRD },
908	{ "ng", 0x80, INSTR_RXY_RRRD },
909	{ "og", 0x81, INSTR_RXY_RRRD },
910	{ "xg", 0x82, INSTR_RXY_RRRD },
911	{ "mlg", 0x86, INSTR_RXY_RRRD },
912	{ "dlg", 0x87, INSTR_RXY_RRRD },
913	{ "alcg", 0x88, INSTR_RXY_RRRD },
914	{ "slbg", 0x89, INSTR_RXY_RRRD },
915	{ "stpq", 0x8e, INSTR_RXY_RRRD },
916	{ "lpq", 0x8f, INSTR_RXY_RRRD },
917	{ "llgc", 0x90, INSTR_RXY_RRRD },
918	{ "llgh", 0x91, INSTR_RXY_RRRD },
919	{ "llc", 0x94, INSTR_RXY_RRRD },
920	{ "llh", 0x95, INSTR_RXY_RRRD },
921#endif
922	{ "lrv", 0x1e, INSTR_RXY_RRRD },
923	{ "lrvh", 0x1f, INSTR_RXY_RRRD },
924	{ "strv", 0x3e, INSTR_RXY_RRRD },
925	{ "ml", 0x96, INSTR_RXY_RRRD },
926	{ "dl", 0x97, INSTR_RXY_RRRD },
927	{ "alc", 0x98, INSTR_RXY_RRRD },
928	{ "slb", 0x99, INSTR_RXY_RRRD },
929	{ "", 0, INSTR_INVALID }
930};
931
932static struct insn opcode_e5[] = {
933#ifdef CONFIG_64BIT
934	{ "strag", 0x02, INSTR_SSE_RDRD },
935#endif
936	{ "lasp", 0x00, INSTR_SSE_RDRD },
937	{ "tprot", 0x01, INSTR_SSE_RDRD },
938	{ "mvcsk", 0x0e, INSTR_SSE_RDRD },
939	{ "mvcdk", 0x0f, INSTR_SSE_RDRD },
940	{ "", 0, INSTR_INVALID }
941};
942
943static struct insn opcode_eb[] = {
944#ifdef CONFIG_64BIT
945	{ "lmg", 0x04, INSTR_RSY_RRRD },
946	{ "srag", 0x0a, INSTR_RSY_RRRD },
947	{ "slag", 0x0b, INSTR_RSY_RRRD },
948	{ "srlg", 0x0c, INSTR_RSY_RRRD },
949	{ "sllg", 0x0d, INSTR_RSY_RRRD },
950	{ "tracg", 0x0f, INSTR_RSY_RRRD },
951	{ "csy", 0x14, INSTR_RSY_RRRD },
952	{ "rllg", 0x1c, INSTR_RSY_RRRD },
953	{ "clmh", 0x20, INSTR_RSY_RURD },
954	{ "clmy", 0x21, INSTR_RSY_RURD },
955	{ "stmg", 0x24, INSTR_RSY_RRRD },
956	{ "stctg", 0x25, INSTR_RSY_CCRD },
957	{ "stmh", 0x26, INSTR_RSY_RRRD },
958	{ "stcmh", 0x2c, INSTR_RSY_RURD },
959	{ "stcmy", 0x2d, INSTR_RSY_RURD },
960	{ "lctlg", 0x2f, INSTR_RSY_CCRD },
961	{ "csg", 0x30, INSTR_RSY_RRRD },
962	{ "cdsy", 0x31, INSTR_RSY_RRRD },
963	{ "cdsg", 0x3e, INSTR_RSY_RRRD },
964	{ "bxhg", 0x44, INSTR_RSY_RRRD },
965	{ "bxleg", 0x45, INSTR_RSY_RRRD },
966	{ "tmy", 0x51, INSTR_SIY_URD },
967	{ "mviy", 0x52, INSTR_SIY_URD },
968	{ "niy", 0x54, INSTR_SIY_URD },
969	{ "cliy", 0x55, INSTR_SIY_URD },
970	{ "oiy", 0x56, INSTR_SIY_URD },
971	{ "xiy", 0x57, INSTR_SIY_URD },
972	{ "icmh", 0x80, INSTR_RSE_RURD },
973	{ "icmh", 0x80, INSTR_RSY_RURD },
974	{ "icmy", 0x81, INSTR_RSY_RURD },
975	{ "clclu", 0x8f, INSTR_RSY_RRRD },
976	{ "stmy", 0x90, INSTR_RSY_RRRD },
977	{ "lmh", 0x96, INSTR_RSY_RRRD },
978	{ "lmy", 0x98, INSTR_RSY_RRRD },
979	{ "lamy", 0x9a, INSTR_RSY_AARD },
980	{ "stamy", 0x9b, INSTR_RSY_AARD },
981#endif
982	{ "rll", 0x1d, INSTR_RSY_RRRD },
983	{ "mvclu", 0x8e, INSTR_RSY_RRRD },
984	{ "tp", 0xc0, INSTR_RSL_R0RD },
985	{ "", 0, INSTR_INVALID }
986};
987
988static struct insn opcode_ec[] = {
989#ifdef CONFIG_64BIT
990	{ "brxhg", 0x44, INSTR_RIE_RRP },
991	{ "brxlg", 0x45, INSTR_RIE_RRP },
992#endif
993	{ "", 0, INSTR_INVALID }
994};
995
996static struct insn opcode_ed[] = {
997#ifdef CONFIG_64BIT
998	{ "mayl", 0x38, INSTR_RXF_FRRDF },
999	{ "myl", 0x39, INSTR_RXF_FRRDF },
1000	{ "may", 0x3a, INSTR_RXF_FRRDF },
1001	{ "my", 0x3b, INSTR_RXF_FRRDF },
1002	{ "mayh", 0x3c, INSTR_RXF_FRRDF },
1003	{ "myh", 0x3d, INSTR_RXF_FRRDF },
1004	{ "ley", 0x64, INSTR_RXY_FRRD },
1005	{ "ldy", 0x65, INSTR_RXY_FRRD },
1006	{ "stey", 0x66, INSTR_RXY_FRRD },
1007	{ "stdy", 0x67, INSTR_RXY_FRRD },
1008#endif
1009	{ "ldeb", 0x04, INSTR_RXE_FRRD },
1010	{ "lxdb", 0x05, INSTR_RXE_FRRD },
1011	{ "lxeb", 0x06, INSTR_RXE_FRRD },
1012	{ "mxdb", 0x07, INSTR_RXE_FRRD },
1013	{ "keb", 0x08, INSTR_RXE_FRRD },
1014	{ "ceb", 0x09, INSTR_RXE_FRRD },
1015	{ "aeb", 0x0a, INSTR_RXE_FRRD },
1016	{ "seb", 0x0b, INSTR_RXE_FRRD },
1017	{ "mdeb", 0x0c, INSTR_RXE_FRRD },
1018	{ "deb", 0x0d, INSTR_RXE_FRRD },
1019	{ "maeb", 0x0e, INSTR_RXF_FRRDF },
1020	{ "mseb", 0x0f, INSTR_RXF_FRRDF },
1021	{ "tceb", 0x10, INSTR_RXE_FRRD },
1022	{ "tcdb", 0x11, INSTR_RXE_FRRD },
1023	{ "tcxb", 0x12, INSTR_RXE_FRRD },
1024	{ "sqeb", 0x14, INSTR_RXE_FRRD },
1025	{ "sqdb", 0x15, INSTR_RXE_FRRD },
1026	{ "meeb", 0x17, INSTR_RXE_FRRD },
1027	{ "kdb", 0x18, INSTR_RXE_FRRD },
1028	{ "cdb", 0x19, INSTR_RXE_FRRD },
1029	{ "adb", 0x1a, INSTR_RXE_FRRD },
1030	{ "sdb", 0x1b, INSTR_RXE_FRRD },
1031	{ "mdb", 0x1c, INSTR_RXE_FRRD },
1032	{ "ddb", 0x1d, INSTR_RXE_FRRD },
1033	{ "madb", 0x1e, INSTR_RXF_FRRDF },
1034	{ "msdb", 0x1f, INSTR_RXF_FRRDF },
1035	{ "lde", 0x24, INSTR_RXE_FRRD },
1036	{ "lxd", 0x25, INSTR_RXE_FRRD },
1037	{ "lxe", 0x26, INSTR_RXE_FRRD },
1038	{ "mae", 0x2e, INSTR_RXF_FRRDF },
1039	{ "mse", 0x2f, INSTR_RXF_FRRDF },
1040	{ "sqe", 0x34, INSTR_RXE_FRRD },
1041	{ "mee", 0x37, INSTR_RXE_FRRD },
1042	{ "mad", 0x3e, INSTR_RXF_FRRDF },
1043	{ "msd", 0x3f, INSTR_RXF_FRRDF },
1044	{ "", 0, INSTR_INVALID }
1045};
1046
1047/* Extracts an operand value from an instruction.  */
1048static unsigned int extract_operand(unsigned char *code,
1049				    const struct operand *operand)
1050{
1051	unsigned int val;
1052	int bits;
1053
1054	/* Extract fragments of the operand byte for byte.  */
1055	code += operand->shift / 8;
1056	bits = (operand->shift & 7) + operand->bits;
1057	val = 0;
1058	do {
1059		val <<= 8;
1060		val |= (unsigned int) *code++;
1061		bits -= 8;
1062	} while (bits > 0);
1063	val >>= -bits;
1064	val &= ((1U << (operand->bits - 1)) << 1) - 1;
1065
1066	/* Check for special long displacement case.  */
1067	if (operand->bits == 20 && operand->shift == 20)
1068		val = (val & 0xff) << 12 | (val & 0xfff00) >> 8;
1069
1070	/* Sign extend value if the operand is signed or pc relative.  */
1071	if ((operand->flags & (OPERAND_SIGNED | OPERAND_PCREL)) &&
1072	    (val & (1U << (operand->bits - 1))))
1073		val |= (-1U << (operand->bits - 1)) << 1;
1074
1075	/* Double value if the operand is pc relative.	*/
1076	if (operand->flags & OPERAND_PCREL)
1077		val <<= 1;
1078
1079	/* Length x in an instructions has real length x + 1.  */
1080	if (operand->flags & OPERAND_LENGTH)
1081		val++;
1082	return val;
1083}
1084
1085static inline int insn_length(unsigned char code)
1086{
1087	return ((((int) code + 64) >> 7) + 1) << 1;
1088}
1089
1090static struct insn *find_insn(unsigned char *code)
1091{
1092	unsigned char opfrag = code[1];
1093	unsigned char opmask;
1094	struct insn *table;
1095
1096	switch (code[0]) {
1097	case 0x01:
1098		table = opcode_01;
1099		break;
1100	case 0xa5:
1101		table = opcode_a5;
1102		break;
1103	case 0xa7:
1104		table = opcode_a7;
1105		break;
1106	case 0xb2:
1107		table = opcode_b2;
1108		break;
1109	case 0xb3:
1110		table = opcode_b3;
1111		break;
1112	case 0xb9:
1113		table = opcode_b9;
1114		break;
1115	case 0xc0:
1116		table = opcode_c0;
1117		break;
1118	case 0xc2:
1119		table = opcode_c2;
1120		break;
1121	case 0xc8:
1122		table = opcode_c8;
1123		break;
1124	case 0xe3:
1125		table = opcode_e3;
1126		opfrag = code[5];
1127		break;
1128	case 0xe5:
1129		table = opcode_e5;
1130		break;
1131	case 0xeb:
1132		table = opcode_eb;
1133		opfrag = code[5];
1134		break;
1135	case 0xec:
1136		table = opcode_ec;
1137		opfrag = code[5];
1138		break;
1139	case 0xed:
1140		table = opcode_ed;
1141		opfrag = code[5];
1142		break;
1143	default:
1144		table = opcode;
1145		opfrag = code[0];
1146		break;
1147	}
1148	while (table->format != INSTR_INVALID) {
1149		opmask = formats[table->format][0];
1150		if (table->opfrag == (opfrag & opmask))
1151			return table;
1152		table++;
1153	}
1154	return NULL;
1155}
1156
1157static int print_insn(char *buffer, unsigned char *code, unsigned long addr)
1158{
1159	struct insn *insn;
1160	const unsigned char *ops;
1161	const struct operand *operand;
1162	unsigned int value;
1163	char separator;
1164	char *ptr;
1165
1166	ptr = buffer;
1167	insn = find_insn(code);
1168	if (insn) {
1169		ptr += sprintf(ptr, "%.5s\t", insn->name);
1170		/* Extract the operands. */
1171		separator = 0;
1172		for (ops = formats[insn->format] + 1; *ops != 0; ops++) {
1173			operand = operands + *ops;
1174			value = extract_operand(code, operand);
1175			if ((operand->flags & OPERAND_INDEX)  && value == 0)
1176				continue;
1177			if ((operand->flags & OPERAND_BASE) &&
1178			    value == 0 && separator == '(') {
1179				separator = ',';
1180				continue;
1181			}
1182			if (separator)
1183				ptr += sprintf(ptr, "%c", separator);
1184			if (operand->flags & OPERAND_GPR)
1185				ptr += sprintf(ptr, "%%r%i", value);
1186			else if (operand->flags & OPERAND_FPR)
1187				ptr += sprintf(ptr, "%%f%i", value);
1188			else if (operand->flags & OPERAND_AR)
1189				ptr += sprintf(ptr, "%%a%i", value);
1190			else if (operand->flags & OPERAND_CR)
1191				ptr += sprintf(ptr, "%%c%i", value);
1192			else if (operand->flags & OPERAND_PCREL)
1193				ptr += sprintf(ptr, "%lx", value + addr);
1194			else if (operand->flags & OPERAND_SIGNED)
1195				ptr += sprintf(ptr, "%i", value);
1196			else
1197				ptr += sprintf(ptr, "%u", value);
1198			if (operand->flags & OPERAND_DISP)
1199				separator = '(';
1200			else if (operand->flags & OPERAND_BASE) {
1201				ptr += sprintf(ptr, ")");
1202				separator = ',';
1203			} else
1204				separator = ',';
1205		}
1206	} else
1207		ptr += sprintf(ptr, "unknown");
1208	return (int) (ptr - buffer);
1209}
1210
1211void show_code(struct pt_regs *regs)
1212{
1213	char *mode = (regs->psw.mask & PSW_MASK_PSTATE) ? "User" : "Krnl";
1214	unsigned char code[64];
1215	char buffer[64], *ptr;
1216	mm_segment_t old_fs;
1217	unsigned long addr;
1218	int start, end, opsize, hops, i;
1219
1220	/* Get a snapshot of the 64 bytes surrounding the fault address. */
1221	old_fs = get_fs();
1222	set_fs((regs->psw.mask & PSW_MASK_PSTATE) ? USER_DS : KERNEL_DS);
1223	for (start = 32; start && regs->psw.addr >= 34 - start; start -= 2) {
1224		addr = regs->psw.addr - 34 + start;
1225		if (__copy_from_user(code + start - 2,
1226				     (char __user *) addr, 2))
1227			break;
1228	}
1229	for (end = 32; end < 64; end += 2) {
1230		addr = regs->psw.addr + end - 32;
1231		if (__copy_from_user(code + end,
1232				     (char __user *) addr, 2))
1233			break;
1234	}
1235	set_fs(old_fs);
1236	/* Code snapshot useable ? */
1237	if ((regs->psw.addr & 1) || start >= end) {
1238		printk("%s Code: Bad PSW.\n", mode);
1239		return;
1240	}
1241	/* Find a starting point for the disassembly. */
1242	while (start < 32) {
1243		hops = 0;
1244		for (i = 0, hops = 0; start + i < 32 && hops < 3; hops++) {
1245			if (!find_insn(code + start + i))
1246				break;
1247			i += insn_length(code[start + i]);
1248		}
1249		if (start + i == 32)
1250			/* Looks good, sequence ends at PSW. */
1251			break;
1252		start += 2;
1253	}
1254	/* Decode the instructions. */
1255	ptr = buffer;
1256	ptr += sprintf(ptr, "%s Code:", mode);
1257	hops = 0;
1258	while (start < end && hops < 8) {
1259		*ptr++ = (start == 32) ? '>' : ' ';
1260		addr = regs->psw.addr + start - 32;
1261		ptr += sprintf(ptr, ONELONG, addr);
1262		opsize = insn_length(code[start]);
1263		if (start + opsize >= end)
1264			break;
1265		for (i = 0; i < opsize; i++)
1266			ptr += sprintf(ptr, "%02x", code[start + i]);
1267		*ptr++ = '\t';
1268		if (i < 6)
1269			*ptr++ = '\t';
1270		ptr += print_insn(ptr, code + start, addr);
1271		start += opsize;
1272		printk(buffer);
1273		ptr = buffer;
1274		ptr += sprintf(ptr, "\n          ");
1275		hops++;
1276	}
1277	printk("\n");
1278}
1279