Merge branch 'linus' into core/objtool, to pick up dependent commits
[sfrench/cifs-2.6.git] / arch / s390 / kernel / dis.c
1 /*
2  * Disassemble s390 instructions.
3  *
4  * Copyright IBM Corp. 2007
5  * Author(s): Martin Schwidefsky (schwidefsky@de.ibm.com),
6  */
7
8 #include <linux/sched.h>
9 #include <linux/kernel.h>
10 #include <linux/string.h>
11 #include <linux/errno.h>
12 #include <linux/ptrace.h>
13 #include <linux/timer.h>
14 #include <linux/mm.h>
15 #include <linux/smp.h>
16 #include <linux/init.h>
17 #include <linux/interrupt.h>
18 #include <linux/delay.h>
19 #include <linux/export.h>
20 #include <linux/kallsyms.h>
21 #include <linux/reboot.h>
22 #include <linux/kprobes.h>
23 #include <linux/kdebug.h>
24 #include <linux/uaccess.h>
25 #include <linux/atomic.h>
26 #include <asm/dis.h>
27 #include <asm/io.h>
28 #include <asm/cpcmd.h>
29 #include <asm/lowcore.h>
30 #include <asm/debug.h>
31 #include <asm/irq.h>
32
33 /* Type of operand */
34 #define OPERAND_GPR     0x1     /* Operand printed as %rx */
35 #define OPERAND_FPR     0x2     /* Operand printed as %fx */
36 #define OPERAND_AR      0x4     /* Operand printed as %ax */
37 #define OPERAND_CR      0x8     /* Operand printed as %cx */
38 #define OPERAND_VR      0x10    /* Operand printed as %vx */
39 #define OPERAND_DISP    0x20    /* Operand printed as displacement */
40 #define OPERAND_BASE    0x40    /* Operand printed as base register */
41 #define OPERAND_INDEX   0x80    /* Operand printed as index register */
42 #define OPERAND_PCREL   0x100   /* Operand printed as pc-relative symbol */
43 #define OPERAND_SIGNED  0x200   /* Operand printed as signed value */
44 #define OPERAND_LENGTH  0x400   /* Operand printed as length (+1) */
45
46 struct s390_operand {
47         unsigned char bits;     /* The number of bits in the operand. */
48         unsigned char shift;    /* The number of bits to shift. */
49         unsigned short flags;   /* One bit syntax flags. */
50 };
51
52 struct s390_insn {
53         union {
54                 const char name[5];
55                 struct {
56                         unsigned char zero;
57                         unsigned int offset;
58                 } __packed;
59         };
60         unsigned char opfrag;
61         unsigned char format;
62 };
63
64 struct s390_opcode_offset {
65         unsigned char opcode;
66         unsigned char mask;
67         unsigned char byte;
68         unsigned short offset;
69         unsigned short count;
70 } __packed;
71
72 enum {
73         UNUSED,
74         A_8,    /* Access reg. starting at position 8 */
75         A_12,   /* Access reg. starting at position 12 */
76         A_24,   /* Access reg. starting at position 24 */
77         A_28,   /* Access reg. starting at position 28 */
78         B_16,   /* Base register starting at position 16 */
79         B_32,   /* Base register starting at position 32 */
80         C_8,    /* Control reg. starting at position 8 */
81         C_12,   /* Control reg. starting at position 12 */
82         D20_20, /* 20 bit displacement starting at 20 */
83         D_20,   /* Displacement starting at position 20 */
84         D_36,   /* Displacement starting at position 36 */
85         F_8,    /* FPR starting at position 8 */
86         F_12,   /* FPR starting at position 12 */
87         F_16,   /* FPR starting at position 16 */
88         F_24,   /* FPR starting at position 24 */
89         F_28,   /* FPR starting at position 28 */
90         F_32,   /* FPR starting at position 32 */
91         I8_8,   /* 8 bit signed value starting at 8 */
92         I8_32,  /* 8 bit signed value starting at 32 */
93         I16_16, /* 16 bit signed value starting at 16 */
94         I16_32, /* 16 bit signed value starting at 32 */
95         I32_16, /* 32 bit signed value starting at 16 */
96         J12_12, /* 12 bit PC relative offset at 12 */
97         J16_16, /* 16 bit PC relative offset at 16 */
98         J16_32, /* 16 bit PC relative offset at 32 */
99         J24_24, /* 24 bit PC relative offset at 24 */
100         J32_16, /* 32 bit PC relative offset at 16 */
101         L4_8,   /* 4 bit length starting at position 8 */
102         L4_12,  /* 4 bit length starting at position 12 */
103         L8_8,   /* 8 bit length starting at position 8 */
104         R_8,    /* GPR starting at position 8 */
105         R_12,   /* GPR starting at position 12 */
106         R_16,   /* GPR starting at position 16 */
107         R_24,   /* GPR starting at position 24 */
108         R_28,   /* GPR starting at position 28 */
109         U4_8,   /* 4 bit unsigned value starting at 8 */
110         U4_12,  /* 4 bit unsigned value starting at 12 */
111         U4_16,  /* 4 bit unsigned value starting at 16 */
112         U4_20,  /* 4 bit unsigned value starting at 20 */
113         U4_24,  /* 4 bit unsigned value starting at 24 */
114         U4_28,  /* 4 bit unsigned value starting at 28 */
115         U4_32,  /* 4 bit unsigned value starting at 32 */
116         U4_36,  /* 4 bit unsigned value starting at 36 */
117         U8_8,   /* 8 bit unsigned value starting at 8 */
118         U8_16,  /* 8 bit unsigned value starting at 16 */
119         U8_24,  /* 8 bit unsigned value starting at 24 */
120         U8_28,  /* 8 bit unsigned value starting at 28 */
121         U8_32,  /* 8 bit unsigned value starting at 32 */
122         U12_16, /* 12 bit unsigned value starting at 16 */
123         U16_16, /* 16 bit unsigned value starting at 16 */
124         U16_32, /* 16 bit unsigned value starting at 32 */
125         U32_16, /* 32 bit unsigned value starting at 16 */
126         VX_12,  /* Vector index register starting at position 12 */
127         V_8,    /* Vector reg. starting at position 8 */
128         V_12,   /* Vector reg. starting at position 12 */
129         V_16,   /* Vector reg. starting at position 16 */
130         V_32,   /* Vector reg. starting at position 32 */
131         X_12,   /* Index register starting at position 12 */
132 };
133
134 static const struct s390_operand operands[] = {
135         [UNUSED] = {  0,  0, 0 },
136         [A_8]    = {  4,  8, OPERAND_AR },
137         [A_12]   = {  4, 12, OPERAND_AR },
138         [A_24]   = {  4, 24, OPERAND_AR },
139         [A_28]   = {  4, 28, OPERAND_AR },
140         [B_16]   = {  4, 16, OPERAND_BASE | OPERAND_GPR },
141         [B_32]   = {  4, 32, OPERAND_BASE | OPERAND_GPR },
142         [C_8]    = {  4,  8, OPERAND_CR },
143         [C_12]   = {  4, 12, OPERAND_CR },
144         [D20_20] = { 20, 20, OPERAND_DISP | OPERAND_SIGNED },
145         [D_20]   = { 12, 20, OPERAND_DISP },
146         [D_36]   = { 12, 36, OPERAND_DISP },
147         [F_8]    = {  4,  8, OPERAND_FPR },
148         [F_12]   = {  4, 12, OPERAND_FPR },
149         [F_16]   = {  4, 16, OPERAND_FPR },
150         [F_24]   = {  4, 24, OPERAND_FPR },
151         [F_28]   = {  4, 28, OPERAND_FPR },
152         [F_32]   = {  4, 32, OPERAND_FPR },
153         [I8_8]   = {  8,  8, OPERAND_SIGNED },
154         [I8_32]  = {  8, 32, OPERAND_SIGNED },
155         [I16_16] = { 16, 16, OPERAND_SIGNED },
156         [I16_32] = { 16, 32, OPERAND_SIGNED },
157         [I32_16] = { 32, 16, OPERAND_SIGNED },
158         [J12_12] = { 12, 12, OPERAND_PCREL },
159         [J16_16] = { 16, 16, OPERAND_PCREL },
160         [J16_32] = { 16, 32, OPERAND_PCREL },
161         [J24_24] = { 24, 24, OPERAND_PCREL },
162         [J32_16] = { 32, 16, OPERAND_PCREL },
163         [L4_8]   = {  4,  8, OPERAND_LENGTH },
164         [L4_12]  = {  4, 12, OPERAND_LENGTH },
165         [L8_8]   = {  8,  8, OPERAND_LENGTH },
166         [R_8]    = {  4,  8, OPERAND_GPR },
167         [R_12]   = {  4, 12, OPERAND_GPR },
168         [R_16]   = {  4, 16, OPERAND_GPR },
169         [R_24]   = {  4, 24, OPERAND_GPR },
170         [R_28]   = {  4, 28, OPERAND_GPR },
171         [U4_8]   = {  4,  8, 0 },
172         [U4_12]  = {  4, 12, 0 },
173         [U4_16]  = {  4, 16, 0 },
174         [U4_20]  = {  4, 20, 0 },
175         [U4_24]  = {  4, 24, 0 },
176         [U4_28]  = {  4, 28, 0 },
177         [U4_32]  = {  4, 32, 0 },
178         [U4_36]  = {  4, 36, 0 },
179         [U8_8]   = {  8,  8, 0 },
180         [U8_16]  = {  8, 16, 0 },
181         [U8_24]  = {  8, 24, 0 },
182         [U8_28]  = {  8, 28, 0 },
183         [U8_32]  = {  8, 32, 0 },
184         [U12_16] = { 12, 16, 0 },
185         [U16_16] = { 16, 16, 0 },
186         [U16_32] = { 16, 32, 0 },
187         [U32_16] = { 32, 16, 0 },
188         [VX_12]  = {  4, 12, OPERAND_INDEX | OPERAND_VR },
189         [V_8]    = {  4,  8, OPERAND_VR },
190         [V_12]   = {  4, 12, OPERAND_VR },
191         [V_16]   = {  4, 16, OPERAND_VR },
192         [V_32]   = {  4, 32, OPERAND_VR },
193         [X_12]   = {  4, 12, OPERAND_INDEX | OPERAND_GPR },
194 };
195
196 static const unsigned char formats[][6] = {
197         [INSTR_E]            = { 0, 0, 0, 0, 0, 0 },
198         [INSTR_IE_UU]        = { U4_24, U4_28, 0, 0, 0, 0 },
199         [INSTR_MII_UPP]      = { U4_8, J12_12, J24_24 },
200         [INSTR_RIE_R0IU]     = { R_8, I16_16, U4_32, 0, 0, 0 },
201         [INSTR_RIE_R0UU]     = { R_8, U16_16, U4_32, 0, 0, 0 },
202         [INSTR_RIE_RRI0]     = { R_8, R_12, I16_16, 0, 0, 0 },
203         [INSTR_RIE_RRP]      = { R_8, R_12, J16_16, 0, 0, 0 },
204         [INSTR_RIE_RRPU]     = { R_8, R_12, U4_32, J16_16, 0, 0 },
205         [INSTR_RIE_RRUUU]    = { R_8, R_12, U8_16, U8_24, U8_32, 0 },
206         [INSTR_RIE_RUI0]     = { R_8, I16_16, U4_12, 0, 0, 0 },
207         [INSTR_RIE_RUPI]     = { R_8, I8_32, U4_12, J16_16, 0, 0 },
208         [INSTR_RIE_RUPU]     = { R_8, U8_32, U4_12, J16_16, 0, 0 },
209         [INSTR_RIL_RI]       = { R_8, I32_16, 0, 0, 0, 0 },
210         [INSTR_RIL_RP]       = { R_8, J32_16, 0, 0, 0, 0 },
211         [INSTR_RIL_RU]       = { R_8, U32_16, 0, 0, 0, 0 },
212         [INSTR_RIL_UP]       = { U4_8, J32_16, 0, 0, 0, 0 },
213         [INSTR_RIS_RURDI]    = { R_8, I8_32, U4_12, D_20, B_16, 0 },
214         [INSTR_RIS_RURDU]    = { R_8, U8_32, U4_12, D_20, B_16, 0 },
215         [INSTR_RI_RI]        = { R_8, I16_16, 0, 0, 0, 0 },
216         [INSTR_RI_RP]        = { R_8, J16_16, 0, 0, 0, 0 },
217         [INSTR_RI_RU]        = { R_8, U16_16, 0, 0, 0, 0 },
218         [INSTR_RI_UP]        = { U4_8, J16_16, 0, 0, 0, 0 },
219         [INSTR_RRE_00]       = { 0, 0, 0, 0, 0, 0 },
220         [INSTR_RRE_AA]       = { A_24, A_28, 0, 0, 0, 0 },
221         [INSTR_RRE_AR]       = { A_24, R_28, 0, 0, 0, 0 },
222         [INSTR_RRE_F0]       = { F_24, 0, 0, 0, 0, 0 },
223         [INSTR_RRE_FF]       = { F_24, F_28, 0, 0, 0, 0 },
224         [INSTR_RRE_FR]       = { F_24, R_28, 0, 0, 0, 0 },
225         [INSTR_RRE_R0]       = { R_24, 0, 0, 0, 0, 0 },
226         [INSTR_RRE_RA]       = { R_24, A_28, 0, 0, 0, 0 },
227         [INSTR_RRE_RF]       = { R_24, F_28, 0, 0, 0, 0 },
228         [INSTR_RRE_RR]       = { R_24, R_28, 0, 0, 0, 0 },
229         [INSTR_RRF_0UFF]     = { F_24, F_28, U4_20, 0, 0, 0 },
230         [INSTR_RRF_0URF]     = { R_24, F_28, U4_20, 0, 0, 0 },
231         [INSTR_RRF_F0FF]     = { F_16, F_24, F_28, 0, 0, 0 },
232         [INSTR_RRF_F0FF2]    = { F_24, F_16, F_28, 0, 0, 0 },
233         [INSTR_RRF_F0FR]     = { F_24, F_16, R_28, 0, 0, 0 },
234         [INSTR_RRF_FFRU]     = { F_24, F_16, R_28, U4_20, 0, 0 },
235         [INSTR_RRF_FUFF]     = { F_24, F_16, F_28, U4_20, 0, 0 },
236         [INSTR_RRF_FUFF2]    = { F_24, F_28, F_16, U4_20, 0, 0 },
237         [INSTR_RRF_R0RR]     = { R_24, R_16, R_28, 0, 0, 0 },
238         [INSTR_RRF_R0RR2]    = { R_24, R_28, R_16, 0, 0, 0 },
239         [INSTR_RRF_RURR]     = { R_24, R_28, R_16, U4_20, 0, 0 },
240         [INSTR_RRF_RURR2]    = { R_24, R_16, R_28, U4_20, 0, 0 },
241         [INSTR_RRF_U0FF]     = { F_24, U4_16, F_28, 0, 0, 0 },
242         [INSTR_RRF_U0RF]     = { R_24, U4_16, F_28, 0, 0, 0 },
243         [INSTR_RRF_U0RR]     = { R_24, R_28, U4_16, 0, 0, 0 },
244         [INSTR_RRF_UUFF]     = { F_24, U4_16, F_28, U4_20, 0, 0 },
245         [INSTR_RRF_UUFR]     = { F_24, U4_16, R_28, U4_20, 0, 0 },
246         [INSTR_RRF_UURF]     = { R_24, U4_16, F_28, U4_20, 0, 0 },
247         [INSTR_RRS_RRRDU]    = { R_8, R_12, U4_32, D_20, B_16 },
248         [INSTR_RR_FF]        = { F_8, F_12, 0, 0, 0, 0 },
249         [INSTR_RR_R0]        = { R_8,  0, 0, 0, 0, 0 },
250         [INSTR_RR_RR]        = { R_8, R_12, 0, 0, 0, 0 },
251         [INSTR_RR_U0]        = { U8_8,  0, 0, 0, 0, 0 },
252         [INSTR_RR_UR]        = { U4_8, R_12, 0, 0, 0, 0 },
253         [INSTR_RSI_RRP]      = { R_8, R_12, J16_16, 0, 0, 0 },
254         [INSTR_RSL_LRDFU]    = { F_32, D_20, L8_8, B_16, U4_36, 0 },
255         [INSTR_RSL_R0RD]     = { D_20, L4_8, B_16, 0, 0, 0 },
256         [INSTR_RSY_AARD]     = { A_8, A_12, D20_20, B_16, 0, 0 },
257         [INSTR_RSY_CCRD]     = { C_8, C_12, D20_20, B_16, 0, 0 },
258         [INSTR_RSY_RDRU]     = { R_8, D20_20, B_16, U4_12, 0, 0 },
259         [INSTR_RSY_RRRD]     = { R_8, R_12, D20_20, B_16, 0, 0 },
260         [INSTR_RSY_RURD]     = { R_8, U4_12, D20_20, B_16, 0, 0 },
261         [INSTR_RSY_RURD2]    = { R_8, D20_20, B_16, U4_12, 0, 0 },
262         [INSTR_RS_AARD]      = { A_8, A_12, D_20, B_16, 0, 0 },
263         [INSTR_RS_CCRD]      = { C_8, C_12, D_20, B_16, 0, 0 },
264         [INSTR_RS_R0RD]      = { R_8, D_20, B_16, 0, 0, 0 },
265         [INSTR_RS_RRRD]      = { R_8, R_12, D_20, B_16, 0, 0 },
266         [INSTR_RS_RURD]      = { R_8, U4_12, D_20, B_16, 0, 0 },
267         [INSTR_RXE_FRRD]     = { F_8, D_20, X_12, B_16, 0, 0 },
268         [INSTR_RXE_RRRDU]    = { R_8, D_20, X_12, B_16, U4_32, 0 },
269         [INSTR_RXF_FRRDF]    = { F_32, F_8, D_20, X_12, B_16, 0 },
270         [INSTR_RXY_FRRD]     = { F_8, D20_20, X_12, B_16, 0, 0 },
271         [INSTR_RXY_RRRD]     = { R_8, D20_20, X_12, B_16, 0, 0 },
272         [INSTR_RXY_URRD]     = { U4_8, D20_20, X_12, B_16, 0, 0 },
273         [INSTR_RX_FRRD]      = { F_8, D_20, X_12, B_16, 0, 0 },
274         [INSTR_RX_RRRD]      = { R_8, D_20, X_12, B_16, 0, 0 },
275         [INSTR_RX_URRD]      = { U4_8, D_20, X_12, B_16, 0, 0 },
276         [INSTR_SIL_RDI]      = { D_20, B_16, I16_32, 0, 0, 0 },
277         [INSTR_SIL_RDU]      = { D_20, B_16, U16_32, 0, 0, 0 },
278         [INSTR_SIY_IRD]      = { D20_20, B_16, I8_8, 0, 0, 0 },
279         [INSTR_SIY_URD]      = { D20_20, B_16, U8_8, 0, 0, 0 },
280         [INSTR_SI_RD]        = { D_20, B_16, 0, 0, 0, 0 },
281         [INSTR_SI_URD]       = { D_20, B_16, U8_8, 0, 0, 0 },
282         [INSTR_SMI_U0RDP]    = { U4_8, J16_32, D_20, B_16, 0, 0 },
283         [INSTR_SSE_RDRD]     = { D_20, B_16, D_36, B_32, 0, 0 },
284         [INSTR_SSF_RRDRD]    = { D_20, B_16, D_36, B_32, R_8, 0 },
285         [INSTR_SSF_RRDRD2]   = { R_8, D_20, B_16, D_36, B_32, 0 },
286         [INSTR_SS_L0RDRD]    = { D_20, L8_8, B_16, D_36, B_32, 0 },
287         [INSTR_SS_L2RDRD]    = { D_20, B_16, D_36, L8_8, B_32, 0 },
288         [INSTR_SS_LIRDRD]    = { D_20, L4_8, B_16, D_36, B_32, U4_12 },
289         [INSTR_SS_LLRDRD]    = { D_20, L4_8, B_16, D_36, L4_12, B_32 },
290         [INSTR_SS_RRRDRD]    = { D_20, R_8, B_16, D_36, B_32, R_12 },
291         [INSTR_SS_RRRDRD2]   = { R_8, D_20, B_16, R_12, D_36, B_32 },
292         [INSTR_SS_RRRDRD3]   = { R_8, R_12, D_20, B_16, D_36, B_32 },
293         [INSTR_S_00]         = { 0, 0, 0, 0, 0, 0 },
294         [INSTR_S_RD]         = { D_20, B_16, 0, 0, 0, 0 },
295         [INSTR_VRI_V0IU]     = { V_8, I16_16, U4_32, 0, 0, 0 },
296         [INSTR_VRI_V0U]      = { V_8, U16_16, 0, 0, 0, 0 },
297         [INSTR_VRI_V0UU2]    = { V_8, U16_16, U4_32, 0, 0, 0 },
298         [INSTR_VRI_V0UUU]    = { V_8, U8_16, U8_24, U4_32, 0, 0 },
299         [INSTR_VRI_VR0UU]    = { V_8, R_12, U8_28, U4_24, 0, 0 },
300         [INSTR_VRI_VVUU]     = { V_8, V_12, U16_16, U4_32, 0, 0 },
301         [INSTR_VRI_VVUUU]    = { V_8, V_12, U12_16, U4_32, U4_28, 0 },
302         [INSTR_VRI_VVUUU2]   = { V_8, V_12, U8_28, U8_16, U4_24, 0 },
303         [INSTR_VRI_VVV0U]    = { V_8, V_12, V_16, U8_24, 0, 0 },
304         [INSTR_VRI_VVV0UU]   = { V_8, V_12, V_16, U8_24, U4_32, 0 },
305         [INSTR_VRI_VVV0UU2]  = { V_8, V_12, V_16, U8_28, U4_24, 0 },
306         [INSTR_VRR_0V]       = { V_12, 0, 0, 0, 0, 0 },
307         [INSTR_VRR_0VV0U]    = { V_12, V_16, U4_24, 0, 0, 0 },
308         [INSTR_VRR_RV0U]     = { R_8, V_12, U4_24, 0, 0, 0 },
309         [INSTR_VRR_VRR]      = { V_8, R_12, R_16, 0, 0, 0 },
310         [INSTR_VRR_VV]       = { V_8, V_12, 0, 0, 0, 0 },
311         [INSTR_VRR_VV0U]     = { V_8, V_12, U4_32, 0, 0, 0 },
312         [INSTR_VRR_VV0U0U]   = { V_8, V_12, U4_32, U4_24, 0, 0 },
313         [INSTR_VRR_VV0UU2]   = { V_8, V_12, U4_32, U4_28, 0, 0 },
314         [INSTR_VRR_VV0UUU]   = { V_8, V_12, U4_32, U4_28, U4_24, 0 },
315         [INSTR_VRR_VVV]      = { V_8, V_12, V_16, 0, 0, 0 },
316         [INSTR_VRR_VVV0U]    = { V_8, V_12, V_16, U4_32, 0, 0 },
317         [INSTR_VRR_VVV0U0U]  = { V_8, V_12, V_16, U4_32, U4_24, 0 },
318         [INSTR_VRR_VVV0UU]   = { V_8, V_12, V_16, U4_32, U4_28, 0 },
319         [INSTR_VRR_VVV0UUU]  = { V_8, V_12, V_16, U4_32, U4_28, U4_24 },
320         [INSTR_VRR_VVV0V]    = { V_8, V_12, V_16, V_32, 0, 0 },
321         [INSTR_VRR_VVVU0UV]  = { V_8, V_12, V_16, V_32, U4_28, U4_20 },
322         [INSTR_VRR_VVVU0V]   = { V_8, V_12, V_16, V_32, U4_20, 0 },
323         [INSTR_VRR_VVVUU0V]  = { V_8, V_12, V_16, V_32, U4_20, U4_24 },
324         [INSTR_VRS_RRDV]     = { V_32, R_12, D_20, B_16, 0, 0 },
325         [INSTR_VRS_RVRDU]    = { R_8, V_12, D_20, B_16, U4_32, 0 },
326         [INSTR_VRS_VRRD]     = { V_8, R_12, D_20, B_16, 0, 0 },
327         [INSTR_VRS_VRRDU]    = { V_8, R_12, D_20, B_16, U4_32, 0 },
328         [INSTR_VRS_VVRD]     = { V_8, V_12, D_20, B_16, 0, 0 },
329         [INSTR_VRS_VVRDU]    = { V_8, V_12, D_20, B_16, U4_32, 0 },
330         [INSTR_VRV_VVXRDU]   = { V_8, D_20, VX_12, B_16, U4_32, 0 },
331         [INSTR_VRX_VRRD]     = { V_8, D_20, X_12, B_16, 0, 0 },
332         [INSTR_VRX_VRRDU]    = { V_8, D_20, X_12, B_16, U4_32, 0 },
333         [INSTR_VRX_VV]       = { V_8, V_12, 0, 0, 0, 0 },
334         [INSTR_VSI_URDV]     = { V_32, D_20, B_16, U8_8, 0, 0 },
335 };
336
337 static char long_insn_name[][7] = LONG_INSN_INITIALIZER;
338 static struct s390_insn opcode[] = OPCODE_TABLE_INITIALIZER;
339 static struct s390_opcode_offset opcode_offset[] = OPCODE_OFFSET_INITIALIZER;
340
341 /* Extracts an operand value from an instruction.  */
342 static unsigned int extract_operand(unsigned char *code,
343                                     const struct s390_operand *operand)
344 {
345         unsigned char *cp;
346         unsigned int val;
347         int bits;
348
349         /* Extract fragments of the operand byte for byte.  */
350         cp = code + operand->shift / 8;
351         bits = (operand->shift & 7) + operand->bits;
352         val = 0;
353         do {
354                 val <<= 8;
355                 val |= (unsigned int) *cp++;
356                 bits -= 8;
357         } while (bits > 0);
358         val >>= -bits;
359         val &= ((1U << (operand->bits - 1)) << 1) - 1;
360
361         /* Check for special long displacement case.  */
362         if (operand->bits == 20 && operand->shift == 20)
363                 val = (val & 0xff) << 12 | (val & 0xfff00) >> 8;
364
365         /* Check for register extensions bits for vector registers. */
366         if (operand->flags & OPERAND_VR) {
367                 if (operand->shift == 8)
368                         val |= (code[4] & 8) << 1;
369                 else if (operand->shift == 12)
370                         val |= (code[4] & 4) << 2;
371                 else if (operand->shift == 16)
372                         val |= (code[4] & 2) << 3;
373                 else if (operand->shift == 32)
374                         val |= (code[4] & 1) << 4;
375         }
376
377         /* Sign extend value if the operand is signed or pc relative.  */
378         if ((operand->flags & (OPERAND_SIGNED | OPERAND_PCREL)) &&
379             (val & (1U << (operand->bits - 1))))
380                 val |= (-1U << (operand->bits - 1)) << 1;
381
382         /* Double value if the operand is pc relative.  */
383         if (operand->flags & OPERAND_PCREL)
384                 val <<= 1;
385
386         /* Length x in an instructions has real length x + 1.  */
387         if (operand->flags & OPERAND_LENGTH)
388                 val++;
389         return val;
390 }
391
392 struct s390_insn *find_insn(unsigned char *code)
393 {
394         struct s390_opcode_offset *entry;
395         struct s390_insn *insn;
396         unsigned char opfrag;
397         int i;
398
399         for (i = 0; i < ARRAY_SIZE(opcode_offset); i++) {
400                 entry = &opcode_offset[i];
401                 if (entry->opcode == code[0] || entry->opcode == 0)
402                         break;
403         }
404
405         opfrag = *(code + entry->byte) & entry->mask;
406
407         insn = &opcode[entry->offset];
408         for (i = 0; i < entry->count; i++) {
409                 if (insn->opfrag == opfrag)
410                         return insn;
411                 insn++;
412         }
413         return NULL;
414 }
415
416 static int print_insn(char *buffer, unsigned char *code, unsigned long addr)
417 {
418         struct s390_insn *insn;
419         const unsigned char *ops;
420         const struct s390_operand *operand;
421         unsigned int value;
422         char separator;
423         char *ptr;
424         int i;
425
426         ptr = buffer;
427         insn = find_insn(code);
428         if (insn) {
429                 if (insn->zero == 0)
430                         ptr += sprintf(ptr, "%.7s\t",
431                                        long_insn_name[insn->offset]);
432                 else
433                         ptr += sprintf(ptr, "%.5s\t", insn->name);
434                 /* Extract the operands. */
435                 separator = 0;
436                 for (ops = formats[insn->format], i = 0;
437                      *ops != 0 && i < 6; ops++, i++) {
438                         operand = operands + *ops;
439                         value = extract_operand(code, operand);
440                         if ((operand->flags & OPERAND_INDEX)  && value == 0)
441                                 continue;
442                         if ((operand->flags & OPERAND_BASE) &&
443                             value == 0 && separator == '(') {
444                                 separator = ',';
445                                 continue;
446                         }
447                         if (separator)
448                                 ptr += sprintf(ptr, "%c", separator);
449                         if (operand->flags & OPERAND_GPR)
450                                 ptr += sprintf(ptr, "%%r%i", value);
451                         else if (operand->flags & OPERAND_FPR)
452                                 ptr += sprintf(ptr, "%%f%i", value);
453                         else if (operand->flags & OPERAND_AR)
454                                 ptr += sprintf(ptr, "%%a%i", value);
455                         else if (operand->flags & OPERAND_CR)
456                                 ptr += sprintf(ptr, "%%c%i", value);
457                         else if (operand->flags & OPERAND_VR)
458                                 ptr += sprintf(ptr, "%%v%i", value);
459                         else if (operand->flags & OPERAND_PCREL)
460                                 ptr += sprintf(ptr, "%lx", (signed int) value
461                                                                       + addr);
462                         else if (operand->flags & OPERAND_SIGNED)
463                                 ptr += sprintf(ptr, "%i", value);
464                         else
465                                 ptr += sprintf(ptr, "%u", value);
466                         if (operand->flags & OPERAND_DISP)
467                                 separator = '(';
468                         else if (operand->flags & OPERAND_BASE) {
469                                 ptr += sprintf(ptr, ")");
470                                 separator = ',';
471                         } else
472                                 separator = ',';
473                 }
474         } else
475                 ptr += sprintf(ptr, "unknown");
476         return (int) (ptr - buffer);
477 }
478
479 void show_code(struct pt_regs *regs)
480 {
481         char *mode = user_mode(regs) ? "User" : "Krnl";
482         unsigned char code[64];
483         char buffer[64], *ptr;
484         mm_segment_t old_fs;
485         unsigned long addr;
486         int start, end, opsize, hops, i;
487
488         /* Get a snapshot of the 64 bytes surrounding the fault address. */
489         old_fs = get_fs();
490         set_fs(user_mode(regs) ? USER_DS : KERNEL_DS);
491         for (start = 32; start && regs->psw.addr >= 34 - start; start -= 2) {
492                 addr = regs->psw.addr - 34 + start;
493                 if (__copy_from_user(code + start - 2,
494                                      (char __user *) addr, 2))
495                         break;
496         }
497         for (end = 32; end < 64; end += 2) {
498                 addr = regs->psw.addr + end - 32;
499                 if (__copy_from_user(code + end,
500                                      (char __user *) addr, 2))
501                         break;
502         }
503         set_fs(old_fs);
504         /* Code snapshot useable ? */
505         if ((regs->psw.addr & 1) || start >= end) {
506                 printk("%s Code: Bad PSW.\n", mode);
507                 return;
508         }
509         /* Find a starting point for the disassembly. */
510         while (start < 32) {
511                 for (i = 0, hops = 0; start + i < 32 && hops < 3; hops++) {
512                         if (!find_insn(code + start + i))
513                                 break;
514                         i += insn_length(code[start + i]);
515                 }
516                 if (start + i == 32)
517                         /* Looks good, sequence ends at PSW. */
518                         break;
519                 start += 2;
520         }
521         /* Decode the instructions. */
522         ptr = buffer;
523         ptr += sprintf(ptr, "%s Code:", mode);
524         hops = 0;
525         while (start < end && hops < 8) {
526                 opsize = insn_length(code[start]);
527                 if  (start + opsize == 32)
528                         *ptr++ = '#';
529                 else if (start == 32)
530                         *ptr++ = '>';
531                 else
532                         *ptr++ = ' ';
533                 addr = regs->psw.addr + start - 32;
534                 ptr += sprintf(ptr, "%016lx: ", addr);
535                 if (start + opsize >= end)
536                         break;
537                 for (i = 0; i < opsize; i++)
538                         ptr += sprintf(ptr, "%02x", code[start + i]);
539                 *ptr++ = '\t';
540                 if (i < 6)
541                         *ptr++ = '\t';
542                 ptr += print_insn(ptr, code + start, addr);
543                 start += opsize;
544                 pr_cont("%s", buffer);
545                 ptr = buffer;
546                 ptr += sprintf(ptr, "\n          ");
547                 hops++;
548         }
549         pr_cont("\n");
550 }
551
552 void print_fn_code(unsigned char *code, unsigned long len)
553 {
554         char buffer[64], *ptr;
555         int opsize, i;
556
557         while (len) {
558                 ptr = buffer;
559                 opsize = insn_length(*code);
560                 if (opsize > len)
561                         break;
562                 ptr += sprintf(ptr, "%p: ", code);
563                 for (i = 0; i < opsize; i++)
564                         ptr += sprintf(ptr, "%02x", code[i]);
565                 *ptr++ = '\t';
566                 if (i < 4)
567                         *ptr++ = '\t';
568                 ptr += print_insn(ptr, code, (unsigned long) code);
569                 *ptr++ = '\n';
570                 *ptr++ = 0;
571                 printk("%s", buffer);
572                 code += opsize;
573                 len -= opsize;
574         }
575 }