diff options
Diffstat (limited to 'arch/sh/kernel/disassemble.c')
-rw-r--r-- | arch/sh/kernel/disassemble.c | 573 |
1 files changed, 573 insertions, 0 deletions
diff --git a/arch/sh/kernel/disassemble.c b/arch/sh/kernel/disassemble.c new file mode 100644 index 000000000000..64d5d8dded7c --- /dev/null +++ b/arch/sh/kernel/disassemble.c | |||
@@ -0,0 +1,573 @@ | |||
1 | /* | ||
2 | * Disassemble SuperH instructions. | ||
3 | * | ||
4 | * Copyright (C) 1999 kaz Kojima | ||
5 | * Copyright (C) 2008 Paul Mundt | ||
6 | * | ||
7 | * This file is subject to the terms and conditions of the GNU General Public | ||
8 | * License. See the file "COPYING" in the main directory of this archive | ||
9 | * for more details. | ||
10 | */ | ||
11 | #include <linux/kernel.h> | ||
12 | #include <linux/string.h> | ||
13 | #include <linux/uaccess.h> | ||
14 | |||
15 | /* | ||
16 | * Format of an instruction in memory. | ||
17 | */ | ||
18 | typedef enum { | ||
19 | HEX_0, HEX_1, HEX_2, HEX_3, HEX_4, HEX_5, HEX_6, HEX_7, | ||
20 | HEX_8, HEX_9, HEX_A, HEX_B, HEX_C, HEX_D, HEX_E, HEX_F, | ||
21 | REG_N, REG_M, REG_NM, REG_B, | ||
22 | BRANCH_12, BRANCH_8, | ||
23 | DISP_8, DISP_4, | ||
24 | IMM_4, IMM_4BY2, IMM_4BY4, PCRELIMM_8BY2, PCRELIMM_8BY4, | ||
25 | IMM_8, IMM_8BY2, IMM_8BY4, | ||
26 | } sh_nibble_type; | ||
27 | |||
28 | typedef enum { | ||
29 | A_END, A_BDISP12, A_BDISP8, | ||
30 | A_DEC_M, A_DEC_N, | ||
31 | A_DISP_GBR, A_DISP_PC, A_DISP_REG_M, A_DISP_REG_N, | ||
32 | A_GBR, | ||
33 | A_IMM, | ||
34 | A_INC_M, A_INC_N, | ||
35 | A_IND_M, A_IND_N, A_IND_R0_REG_M, A_IND_R0_REG_N, | ||
36 | A_MACH, A_MACL, | ||
37 | A_PR, A_R0, A_R0_GBR, A_REG_M, A_REG_N, A_REG_B, | ||
38 | A_SR, A_VBR, A_SSR, A_SPC, A_SGR, A_DBR, | ||
39 | F_REG_N, F_REG_M, D_REG_N, D_REG_M, | ||
40 | X_REG_N, /* Only used for argument parsing */ | ||
41 | X_REG_M, /* Only used for argument parsing */ | ||
42 | DX_REG_N, DX_REG_M, V_REG_N, V_REG_M, | ||
43 | FD_REG_N, | ||
44 | XMTRX_M4, | ||
45 | F_FR0, | ||
46 | FPUL_N, FPUL_M, FPSCR_N, FPSCR_M, | ||
47 | } sh_arg_type; | ||
48 | |||
49 | static struct sh_opcode_info { | ||
50 | char *name; | ||
51 | sh_arg_type arg[7]; | ||
52 | sh_nibble_type nibbles[4]; | ||
53 | } sh_table[] = { | ||
54 | {"add",{A_IMM,A_REG_N},{HEX_7,REG_N,IMM_8}}, | ||
55 | {"add",{ A_REG_M,A_REG_N},{HEX_3,REG_N,REG_M,HEX_C}}, | ||
56 | {"addc",{ A_REG_M,A_REG_N},{HEX_3,REG_N,REG_M,HEX_E}}, | ||
57 | {"addv",{ A_REG_M,A_REG_N},{HEX_3,REG_N,REG_M,HEX_F}}, | ||
58 | {"and",{A_IMM,A_R0},{HEX_C,HEX_9,IMM_8}}, | ||
59 | {"and",{ A_REG_M,A_REG_N},{HEX_2,REG_N,REG_M,HEX_9}}, | ||
60 | {"and.b",{A_IMM,A_R0_GBR},{HEX_C,HEX_D,IMM_8}}, | ||
61 | {"bra",{A_BDISP12},{HEX_A,BRANCH_12}}, | ||
62 | {"bsr",{A_BDISP12},{HEX_B,BRANCH_12}}, | ||
63 | {"bt",{A_BDISP8},{HEX_8,HEX_9,BRANCH_8}}, | ||
64 | {"bf",{A_BDISP8},{HEX_8,HEX_B,BRANCH_8}}, | ||
65 | {"bt.s",{A_BDISP8},{HEX_8,HEX_D,BRANCH_8}}, | ||
66 | {"bt/s",{A_BDISP8},{HEX_8,HEX_D,BRANCH_8}}, | ||
67 | {"bf.s",{A_BDISP8},{HEX_8,HEX_F,BRANCH_8}}, | ||
68 | {"bf/s",{A_BDISP8},{HEX_8,HEX_F,BRANCH_8}}, | ||
69 | {"clrmac",{0},{HEX_0,HEX_0,HEX_2,HEX_8}}, | ||
70 | {"clrs",{0},{HEX_0,HEX_0,HEX_4,HEX_8}}, | ||
71 | {"clrt",{0},{HEX_0,HEX_0,HEX_0,HEX_8}}, | ||
72 | {"cmp/eq",{A_IMM,A_R0},{HEX_8,HEX_8,IMM_8}}, | ||
73 | {"cmp/eq",{ A_REG_M,A_REG_N},{HEX_3,REG_N,REG_M,HEX_0}}, | ||
74 | {"cmp/ge",{ A_REG_M,A_REG_N},{HEX_3,REG_N,REG_M,HEX_3}}, | ||
75 | {"cmp/gt",{ A_REG_M,A_REG_N},{HEX_3,REG_N,REG_M,HEX_7}}, | ||
76 | {"cmp/hi",{ A_REG_M,A_REG_N},{HEX_3,REG_N,REG_M,HEX_6}}, | ||
77 | {"cmp/hs",{ A_REG_M,A_REG_N},{HEX_3,REG_N,REG_M,HEX_2}}, | ||
78 | {"cmp/pl",{A_REG_N},{HEX_4,REG_N,HEX_1,HEX_5}}, | ||
79 | {"cmp/pz",{A_REG_N},{HEX_4,REG_N,HEX_1,HEX_1}}, | ||
80 | {"cmp/str",{ A_REG_M,A_REG_N},{HEX_2,REG_N,REG_M,HEX_C}}, | ||
81 | {"div0s",{ A_REG_M,A_REG_N},{HEX_2,REG_N,REG_M,HEX_7}}, | ||
82 | {"div0u",{0},{HEX_0,HEX_0,HEX_1,HEX_9}}, | ||
83 | {"div1",{ A_REG_M,A_REG_N},{HEX_3,REG_N,REG_M,HEX_4}}, | ||
84 | {"exts.b",{ A_REG_M,A_REG_N},{HEX_6,REG_N,REG_M,HEX_E}}, | ||
85 | {"exts.w",{ A_REG_M,A_REG_N},{HEX_6,REG_N,REG_M,HEX_F}}, | ||
86 | {"extu.b",{ A_REG_M,A_REG_N},{HEX_6,REG_N,REG_M,HEX_C}}, | ||
87 | {"extu.w",{ A_REG_M,A_REG_N},{HEX_6,REG_N,REG_M,HEX_D}}, | ||
88 | {"jmp",{A_IND_N},{HEX_4,REG_N,HEX_2,HEX_B}}, | ||
89 | {"jsr",{A_IND_N},{HEX_4,REG_N,HEX_0,HEX_B}}, | ||
90 | {"ldc",{A_REG_N,A_SR},{HEX_4,REG_N,HEX_0,HEX_E}}, | ||
91 | {"ldc",{A_REG_N,A_GBR},{HEX_4,REG_N,HEX_1,HEX_E}}, | ||
92 | {"ldc",{A_REG_N,A_VBR},{HEX_4,REG_N,HEX_2,HEX_E}}, | ||
93 | {"ldc",{A_REG_N,A_SSR},{HEX_4,REG_N,HEX_3,HEX_E}}, | ||
94 | {"ldc",{A_REG_N,A_SPC},{HEX_4,REG_N,HEX_4,HEX_E}}, | ||
95 | {"ldc",{A_REG_N,A_DBR},{HEX_4,REG_N,HEX_7,HEX_E}}, | ||
96 | {"ldc",{A_REG_N,A_REG_B},{HEX_4,REG_N,REG_B,HEX_E}}, | ||
97 | {"ldc.l",{A_INC_N,A_SR},{HEX_4,REG_N,HEX_0,HEX_7}}, | ||
98 | {"ldc.l",{A_INC_N,A_GBR},{HEX_4,REG_N,HEX_1,HEX_7}}, | ||
99 | {"ldc.l",{A_INC_N,A_VBR},{HEX_4,REG_N,HEX_2,HEX_7}}, | ||
100 | {"ldc.l",{A_INC_N,A_SSR},{HEX_4,REG_N,HEX_3,HEX_7}}, | ||
101 | {"ldc.l",{A_INC_N,A_SPC},{HEX_4,REG_N,HEX_4,HEX_7}}, | ||
102 | {"ldc.l",{A_INC_N,A_DBR},{HEX_4,REG_N,HEX_7,HEX_7}}, | ||
103 | {"ldc.l",{A_INC_N,A_REG_B},{HEX_4,REG_N,REG_B,HEX_7}}, | ||
104 | {"lds",{A_REG_N,A_MACH},{HEX_4,REG_N,HEX_0,HEX_A}}, | ||
105 | {"lds",{A_REG_N,A_MACL},{HEX_4,REG_N,HEX_1,HEX_A}}, | ||
106 | {"lds",{A_REG_N,A_PR},{HEX_4,REG_N,HEX_2,HEX_A}}, | ||
107 | {"lds",{A_REG_M,FPUL_N},{HEX_4,REG_M,HEX_5,HEX_A}}, | ||
108 | {"lds",{A_REG_M,FPSCR_N},{HEX_4,REG_M,HEX_6,HEX_A}}, | ||
109 | {"lds.l",{A_INC_N,A_MACH},{HEX_4,REG_N,HEX_0,HEX_6}}, | ||
110 | {"lds.l",{A_INC_N,A_MACL},{HEX_4,REG_N,HEX_1,HEX_6}}, | ||
111 | {"lds.l",{A_INC_N,A_PR},{HEX_4,REG_N,HEX_2,HEX_6}}, | ||
112 | {"lds.l",{A_INC_M,FPUL_N},{HEX_4,REG_M,HEX_5,HEX_6}}, | ||
113 | {"lds.l",{A_INC_M,FPSCR_N},{HEX_4,REG_M,HEX_6,HEX_6}}, | ||
114 | {"ldtlb",{0},{HEX_0,HEX_0,HEX_3,HEX_8}}, | ||
115 | {"mac.w",{A_INC_M,A_INC_N},{HEX_4,REG_N,REG_M,HEX_F}}, | ||
116 | {"mov",{A_IMM,A_REG_N},{HEX_E,REG_N,IMM_8}}, | ||
117 | {"mov",{ A_REG_M,A_REG_N},{HEX_6,REG_N,REG_M,HEX_3}}, | ||
118 | {"mov.b",{ A_REG_M,A_IND_R0_REG_N},{HEX_0,REG_N,REG_M,HEX_4}}, | ||
119 | {"mov.b",{ A_REG_M,A_DEC_N},{HEX_2,REG_N,REG_M,HEX_4}}, | ||
120 | {"mov.b",{ A_REG_M,A_IND_N},{HEX_2,REG_N,REG_M,HEX_0}}, | ||
121 | {"mov.b",{A_DISP_REG_M,A_R0},{HEX_8,HEX_4,REG_M,IMM_4}}, | ||
122 | {"mov.b",{A_DISP_GBR,A_R0},{HEX_C,HEX_4,IMM_8}}, | ||
123 | {"mov.b",{A_IND_R0_REG_M,A_REG_N},{HEX_0,REG_N,REG_M,HEX_C}}, | ||
124 | {"mov.b",{A_INC_M,A_REG_N},{HEX_6,REG_N,REG_M,HEX_4}}, | ||
125 | {"mov.b",{A_IND_M,A_REG_N},{HEX_6,REG_N,REG_M,HEX_0}}, | ||
126 | {"mov.b",{A_R0,A_DISP_REG_M},{HEX_8,HEX_0,REG_M,IMM_4}}, | ||
127 | {"mov.b",{A_R0,A_DISP_GBR},{HEX_C,HEX_0,IMM_8}}, | ||
128 | {"mov.l",{ A_REG_M,A_DISP_REG_N},{HEX_1,REG_N,REG_M,IMM_4BY4}}, | ||
129 | {"mov.l",{ A_REG_M,A_IND_R0_REG_N},{HEX_0,REG_N,REG_M,HEX_6}}, | ||
130 | {"mov.l",{ A_REG_M,A_DEC_N},{HEX_2,REG_N,REG_M,HEX_6}}, | ||
131 | {"mov.l",{ A_REG_M,A_IND_N},{HEX_2,REG_N,REG_M,HEX_2}}, | ||
132 | {"mov.l",{A_DISP_REG_M,A_REG_N},{HEX_5,REG_N,REG_M,IMM_4BY4}}, | ||
133 | {"mov.l",{A_DISP_GBR,A_R0},{HEX_C,HEX_6,IMM_8BY4}}, | ||
134 | {"mov.l",{A_DISP_PC,A_REG_N},{HEX_D,REG_N,PCRELIMM_8BY4}}, | ||
135 | {"mov.l",{A_IND_R0_REG_M,A_REG_N},{HEX_0,REG_N,REG_M,HEX_E}}, | ||
136 | {"mov.l",{A_INC_M,A_REG_N},{HEX_6,REG_N,REG_M,HEX_6}}, | ||
137 | {"mov.l",{A_IND_M,A_REG_N},{HEX_6,REG_N,REG_M,HEX_2}}, | ||
138 | {"mov.l",{A_R0,A_DISP_GBR},{HEX_C,HEX_2,IMM_8BY4}}, | ||
139 | {"mov.w",{ A_REG_M,A_IND_R0_REG_N},{HEX_0,REG_N,REG_M,HEX_5}}, | ||
140 | {"mov.w",{ A_REG_M,A_DEC_N},{HEX_2,REG_N,REG_M,HEX_5}}, | ||
141 | {"mov.w",{ A_REG_M,A_IND_N},{HEX_2,REG_N,REG_M,HEX_1}}, | ||
142 | {"mov.w",{A_DISP_REG_M,A_R0},{HEX_8,HEX_5,REG_M,IMM_4BY2}}, | ||
143 | {"mov.w",{A_DISP_GBR,A_R0},{HEX_C,HEX_5,IMM_8BY2}}, | ||
144 | {"mov.w",{A_DISP_PC,A_REG_N},{HEX_9,REG_N,PCRELIMM_8BY2}}, | ||
145 | {"mov.w",{A_IND_R0_REG_M,A_REG_N},{HEX_0,REG_N,REG_M,HEX_D}}, | ||
146 | {"mov.w",{A_INC_M,A_REG_N},{HEX_6,REG_N,REG_M,HEX_5}}, | ||
147 | {"mov.w",{A_IND_M,A_REG_N},{HEX_6,REG_N,REG_M,HEX_1}}, | ||
148 | {"mov.w",{A_R0,A_DISP_REG_M},{HEX_8,HEX_1,REG_M,IMM_4BY2}}, | ||
149 | {"mov.w",{A_R0,A_DISP_GBR},{HEX_C,HEX_1,IMM_8BY2}}, | ||
150 | {"mova",{A_DISP_PC,A_R0},{HEX_C,HEX_7,PCRELIMM_8BY4}}, | ||
151 | {"movca.l",{A_R0,A_IND_N},{HEX_0,REG_N,HEX_C,HEX_3}}, | ||
152 | {"movt",{A_REG_N},{HEX_0,REG_N,HEX_2,HEX_9}}, | ||
153 | {"muls",{ A_REG_M,A_REG_N},{HEX_2,REG_N,REG_M,HEX_F}}, | ||
154 | {"mul.l",{ A_REG_M,A_REG_N},{HEX_0,REG_N,REG_M,HEX_7}}, | ||
155 | {"mulu",{ A_REG_M,A_REG_N},{HEX_2,REG_N,REG_M,HEX_E}}, | ||
156 | {"neg",{ A_REG_M,A_REG_N},{HEX_6,REG_N,REG_M,HEX_B}}, | ||
157 | {"negc",{ A_REG_M,A_REG_N},{HEX_6,REG_N,REG_M,HEX_A}}, | ||
158 | {"nop",{0},{HEX_0,HEX_0,HEX_0,HEX_9}}, | ||
159 | {"not",{ A_REG_M,A_REG_N},{HEX_6,REG_N,REG_M,HEX_7}}, | ||
160 | {"ocbi",{A_IND_N},{HEX_0,REG_N,HEX_9,HEX_3}}, | ||
161 | {"ocbp",{A_IND_N},{HEX_0,REG_N,HEX_A,HEX_3}}, | ||
162 | {"ocbwb",{A_IND_N},{HEX_0,REG_N,HEX_B,HEX_3}}, | ||
163 | {"or",{A_IMM,A_R0},{HEX_C,HEX_B,IMM_8}}, | ||
164 | {"or",{ A_REG_M,A_REG_N},{HEX_2,REG_N,REG_M,HEX_B}}, | ||
165 | {"or.b",{A_IMM,A_R0_GBR},{HEX_C,HEX_F,IMM_8}}, | ||
166 | {"pref",{A_IND_N},{HEX_0,REG_N,HEX_8,HEX_3}}, | ||
167 | {"rotcl",{A_REG_N},{HEX_4,REG_N,HEX_2,HEX_4}}, | ||
168 | {"rotcr",{A_REG_N},{HEX_4,REG_N,HEX_2,HEX_5}}, | ||
169 | {"rotl",{A_REG_N},{HEX_4,REG_N,HEX_0,HEX_4}}, | ||
170 | {"rotr",{A_REG_N},{HEX_4,REG_N,HEX_0,HEX_5}}, | ||
171 | {"rte",{0},{HEX_0,HEX_0,HEX_2,HEX_B}}, | ||
172 | {"rts",{0},{HEX_0,HEX_0,HEX_0,HEX_B}}, | ||
173 | {"sets",{0},{HEX_0,HEX_0,HEX_5,HEX_8}}, | ||
174 | {"sett",{0},{HEX_0,HEX_0,HEX_1,HEX_8}}, | ||
175 | {"shad",{ A_REG_M,A_REG_N},{HEX_4,REG_N,REG_M,HEX_C}}, | ||
176 | {"shld",{ A_REG_M,A_REG_N},{HEX_4,REG_N,REG_M,HEX_D}}, | ||
177 | {"shal",{A_REG_N},{HEX_4,REG_N,HEX_2,HEX_0}}, | ||
178 | {"shar",{A_REG_N},{HEX_4,REG_N,HEX_2,HEX_1}}, | ||
179 | {"shll",{A_REG_N},{HEX_4,REG_N,HEX_0,HEX_0}}, | ||
180 | {"shll16",{A_REG_N},{HEX_4,REG_N,HEX_2,HEX_8}}, | ||
181 | {"shll2",{A_REG_N},{HEX_4,REG_N,HEX_0,HEX_8}}, | ||
182 | {"shll8",{A_REG_N},{HEX_4,REG_N,HEX_1,HEX_8}}, | ||
183 | {"shlr",{A_REG_N},{HEX_4,REG_N,HEX_0,HEX_1}}, | ||
184 | {"shlr16",{A_REG_N},{HEX_4,REG_N,HEX_2,HEX_9}}, | ||
185 | {"shlr2",{A_REG_N},{HEX_4,REG_N,HEX_0,HEX_9}}, | ||
186 | {"shlr8",{A_REG_N},{HEX_4,REG_N,HEX_1,HEX_9}}, | ||
187 | {"sleep",{0},{HEX_0,HEX_0,HEX_1,HEX_B}}, | ||
188 | {"stc",{A_SR,A_REG_N},{HEX_0,REG_N,HEX_0,HEX_2}}, | ||
189 | {"stc",{A_GBR,A_REG_N},{HEX_0,REG_N,HEX_1,HEX_2}}, | ||
190 | {"stc",{A_VBR,A_REG_N},{HEX_0,REG_N,HEX_2,HEX_2}}, | ||
191 | {"stc",{A_SSR,A_REG_N},{HEX_0,REG_N,HEX_3,HEX_2}}, | ||
192 | {"stc",{A_SPC,A_REG_N},{HEX_0,REG_N,HEX_4,HEX_2}}, | ||
193 | {"stc",{A_SGR,A_REG_N},{HEX_0,REG_N,HEX_6,HEX_2}}, | ||
194 | {"stc",{A_DBR,A_REG_N},{HEX_0,REG_N,HEX_7,HEX_2}}, | ||
195 | {"stc",{A_REG_B,A_REG_N},{HEX_0,REG_N,REG_B,HEX_2}}, | ||
196 | {"stc.l",{A_SR,A_DEC_N},{HEX_4,REG_N,HEX_0,HEX_3}}, | ||
197 | {"stc.l",{A_GBR,A_DEC_N},{HEX_4,REG_N,HEX_1,HEX_3}}, | ||
198 | {"stc.l",{A_VBR,A_DEC_N},{HEX_4,REG_N,HEX_2,HEX_3}}, | ||
199 | {"stc.l",{A_SSR,A_DEC_N},{HEX_4,REG_N,HEX_3,HEX_3}}, | ||
200 | {"stc.l",{A_SPC,A_DEC_N},{HEX_4,REG_N,HEX_4,HEX_3}}, | ||
201 | {"stc.l",{A_SGR,A_DEC_N},{HEX_4,REG_N,HEX_6,HEX_3}}, | ||
202 | {"stc.l",{A_DBR,A_DEC_N},{HEX_4,REG_N,HEX_7,HEX_3}}, | ||
203 | {"stc.l",{A_REG_B,A_DEC_N},{HEX_4,REG_N,REG_B,HEX_3}}, | ||
204 | {"sts",{A_MACH,A_REG_N},{HEX_0,REG_N,HEX_0,HEX_A}}, | ||
205 | {"sts",{A_MACL,A_REG_N},{HEX_0,REG_N,HEX_1,HEX_A}}, | ||
206 | {"sts",{A_PR,A_REG_N},{HEX_0,REG_N,HEX_2,HEX_A}}, | ||
207 | {"sts",{FPUL_M,A_REG_N},{HEX_0,REG_N,HEX_5,HEX_A}}, | ||
208 | {"sts",{FPSCR_M,A_REG_N},{HEX_0,REG_N,HEX_6,HEX_A}}, | ||
209 | {"sts.l",{A_MACH,A_DEC_N},{HEX_4,REG_N,HEX_0,HEX_2}}, | ||
210 | {"sts.l",{A_MACL,A_DEC_N},{HEX_4,REG_N,HEX_1,HEX_2}}, | ||
211 | {"sts.l",{A_PR,A_DEC_N},{HEX_4,REG_N,HEX_2,HEX_2}}, | ||
212 | {"sts.l",{FPUL_M,A_DEC_N},{HEX_4,REG_N,HEX_5,HEX_2}}, | ||
213 | {"sts.l",{FPSCR_M,A_DEC_N},{HEX_4,REG_N,HEX_6,HEX_2}}, | ||
214 | {"sub",{ A_REG_M,A_REG_N},{HEX_3,REG_N,REG_M,HEX_8}}, | ||
215 | {"subc",{ A_REG_M,A_REG_N},{HEX_3,REG_N,REG_M,HEX_A}}, | ||
216 | {"subv",{ A_REG_M,A_REG_N},{HEX_3,REG_N,REG_M,HEX_B}}, | ||
217 | {"swap.b",{ A_REG_M,A_REG_N},{HEX_6,REG_N,REG_M,HEX_8}}, | ||
218 | {"swap.w",{ A_REG_M,A_REG_N},{HEX_6,REG_N,REG_M,HEX_9}}, | ||
219 | {"tas.b",{A_IND_N},{HEX_4,REG_N,HEX_1,HEX_B}}, | ||
220 | {"trapa",{A_IMM},{HEX_C,HEX_3,IMM_8}}, | ||
221 | {"tst",{A_IMM,A_R0},{HEX_C,HEX_8,IMM_8}}, | ||
222 | {"tst",{ A_REG_M,A_REG_N},{HEX_2,REG_N,REG_M,HEX_8}}, | ||
223 | {"tst.b",{A_IMM,A_R0_GBR},{HEX_C,HEX_C,IMM_8}}, | ||
224 | {"xor",{A_IMM,A_R0},{HEX_C,HEX_A,IMM_8}}, | ||
225 | {"xor",{ A_REG_M,A_REG_N},{HEX_2,REG_N,REG_M,HEX_A}}, | ||
226 | {"xor.b",{A_IMM,A_R0_GBR},{HEX_C,HEX_E,IMM_8}}, | ||
227 | {"xtrct",{ A_REG_M,A_REG_N},{HEX_2,REG_N,REG_M,HEX_D}}, | ||
228 | {"mul.l",{ A_REG_M,A_REG_N},{HEX_0,REG_N,REG_M,HEX_7}}, | ||
229 | {"dt",{A_REG_N},{HEX_4,REG_N,HEX_1,HEX_0}}, | ||
230 | {"dmuls.l",{ A_REG_M,A_REG_N},{HEX_3,REG_N,REG_M,HEX_D}}, | ||
231 | {"dmulu.l",{ A_REG_M,A_REG_N},{HEX_3,REG_N,REG_M,HEX_5}}, | ||
232 | {"mac.l",{A_INC_M,A_INC_N},{HEX_0,REG_N,REG_M,HEX_F}}, | ||
233 | {"braf",{A_REG_N},{HEX_0,REG_N,HEX_2,HEX_3}}, | ||
234 | {"bsrf",{A_REG_N},{HEX_0,REG_N,HEX_0,HEX_3}}, | ||
235 | {"fabs",{FD_REG_N},{HEX_F,REG_N,HEX_5,HEX_D}}, | ||
236 | {"fadd",{F_REG_M,F_REG_N},{HEX_F,REG_N,REG_M,HEX_0}}, | ||
237 | {"fadd",{D_REG_M,D_REG_N},{HEX_F,REG_N,REG_M,HEX_0}}, | ||
238 | {"fcmp/eq",{F_REG_M,F_REG_N},{HEX_F,REG_N,REG_M,HEX_4}}, | ||
239 | {"fcmp/eq",{D_REG_M,D_REG_N},{HEX_F,REG_N,REG_M,HEX_4}}, | ||
240 | {"fcmp/gt",{F_REG_M,F_REG_N},{HEX_F,REG_N,REG_M,HEX_5}}, | ||
241 | {"fcmp/gt",{D_REG_M,D_REG_N},{HEX_F,REG_N,REG_M,HEX_5}}, | ||
242 | {"fcnvds",{D_REG_N,FPUL_M},{HEX_F,REG_N,HEX_B,HEX_D}}, | ||
243 | {"fcnvsd",{FPUL_M,D_REG_N},{HEX_F,REG_N,HEX_A,HEX_D}}, | ||
244 | {"fdiv",{F_REG_M,F_REG_N},{HEX_F,REG_N,REG_M,HEX_3}}, | ||
245 | {"fdiv",{D_REG_M,D_REG_N},{HEX_F,REG_N,REG_M,HEX_3}}, | ||
246 | {"fipr",{V_REG_M,V_REG_N},{HEX_F,REG_NM,HEX_E,HEX_D}}, | ||
247 | {"fldi0",{F_REG_N},{HEX_F,REG_N,HEX_8,HEX_D}}, | ||
248 | {"fldi1",{F_REG_N},{HEX_F,REG_N,HEX_9,HEX_D}}, | ||
249 | {"flds",{F_REG_N,FPUL_M},{HEX_F,REG_N,HEX_1,HEX_D}}, | ||
250 | {"float",{FPUL_M,FD_REG_N},{HEX_F,REG_N,HEX_2,HEX_D}}, | ||
251 | {"fmac",{F_FR0,F_REG_M,F_REG_N},{HEX_F,REG_N,REG_M,HEX_E}}, | ||
252 | {"fmov",{F_REG_M,F_REG_N},{HEX_F,REG_N,REG_M,HEX_C}}, | ||
253 | {"fmov",{DX_REG_M,DX_REG_N},{HEX_F,REG_N,REG_M,HEX_C}}, | ||
254 | {"fmov",{A_IND_M,F_REG_N},{HEX_F,REG_N,REG_M,HEX_8}}, | ||
255 | {"fmov",{A_IND_M,DX_REG_N},{HEX_F,REG_N,REG_M,HEX_8}}, | ||
256 | {"fmov",{F_REG_M,A_IND_N},{HEX_F,REG_N,REG_M,HEX_A}}, | ||
257 | {"fmov",{DX_REG_M,A_IND_N},{HEX_F,REG_N,REG_M,HEX_A}}, | ||
258 | {"fmov",{A_INC_M,F_REG_N},{HEX_F,REG_N,REG_M,HEX_9}}, | ||
259 | {"fmov",{A_INC_M,DX_REG_N},{HEX_F,REG_N,REG_M,HEX_9}}, | ||
260 | {"fmov",{F_REG_M,A_DEC_N},{HEX_F,REG_N,REG_M,HEX_B}}, | ||
261 | {"fmov",{DX_REG_M,A_DEC_N},{HEX_F,REG_N,REG_M,HEX_B}}, | ||
262 | {"fmov",{A_IND_R0_REG_M,F_REG_N},{HEX_F,REG_N,REG_M,HEX_6}}, | ||
263 | {"fmov",{A_IND_R0_REG_M,DX_REG_N},{HEX_F,REG_N,REG_M,HEX_6}}, | ||
264 | {"fmov",{F_REG_M,A_IND_R0_REG_N},{HEX_F,REG_N,REG_M,HEX_7}}, | ||
265 | {"fmov",{DX_REG_M,A_IND_R0_REG_N},{HEX_F,REG_N,REG_M,HEX_7}}, | ||
266 | {"fmov.d",{A_IND_M,DX_REG_N},{HEX_F,REG_N,REG_M,HEX_8}}, | ||
267 | {"fmov.d",{DX_REG_M,A_IND_N},{HEX_F,REG_N,REG_M,HEX_A}}, | ||
268 | {"fmov.d",{A_INC_M,DX_REG_N},{HEX_F,REG_N,REG_M,HEX_9}}, | ||
269 | {"fmov.d",{DX_REG_M,A_DEC_N},{HEX_F,REG_N,REG_M,HEX_B}}, | ||
270 | {"fmov.d",{A_IND_R0_REG_M,DX_REG_N},{HEX_F,REG_N,REG_M,HEX_6}}, | ||
271 | {"fmov.d",{DX_REG_M,A_IND_R0_REG_N},{HEX_F,REG_N,REG_M,HEX_7}}, | ||
272 | {"fmov.s",{A_IND_M,F_REG_N},{HEX_F,REG_N,REG_M,HEX_8}}, | ||
273 | {"fmov.s",{F_REG_M,A_IND_N},{HEX_F,REG_N,REG_M,HEX_A}}, | ||
274 | {"fmov.s",{A_INC_M,F_REG_N},{HEX_F,REG_N,REG_M,HEX_9}}, | ||
275 | {"fmov.s",{F_REG_M,A_DEC_N},{HEX_F,REG_N,REG_M,HEX_B}}, | ||
276 | {"fmov.s",{A_IND_R0_REG_M,F_REG_N},{HEX_F,REG_N,REG_M,HEX_6}}, | ||
277 | {"fmov.s",{F_REG_M,A_IND_R0_REG_N},{HEX_F,REG_N,REG_M,HEX_7}}, | ||
278 | {"fmul",{F_REG_M,F_REG_N},{HEX_F,REG_N,REG_M,HEX_2}}, | ||
279 | {"fmul",{D_REG_M,D_REG_N},{HEX_F,REG_N,REG_M,HEX_2}}, | ||
280 | {"fneg",{FD_REG_N},{HEX_F,REG_N,HEX_4,HEX_D}}, | ||
281 | {"frchg",{0},{HEX_F,HEX_B,HEX_F,HEX_D}}, | ||
282 | {"fschg",{0},{HEX_F,HEX_3,HEX_F,HEX_D}}, | ||
283 | {"fsqrt",{FD_REG_N},{HEX_F,REG_N,HEX_6,HEX_D}}, | ||
284 | {"fsts",{FPUL_M,F_REG_N},{HEX_F,REG_N,HEX_0,HEX_D}}, | ||
285 | {"fsub",{F_REG_M,F_REG_N},{HEX_F,REG_N,REG_M,HEX_1}}, | ||
286 | {"fsub",{D_REG_M,D_REG_N},{HEX_F,REG_N,REG_M,HEX_1}}, | ||
287 | {"ftrc",{FD_REG_N,FPUL_M},{HEX_F,REG_N,HEX_3,HEX_D}}, | ||
288 | {"ftrv",{XMTRX_M4,V_REG_N},{HEX_F,REG_NM,HEX_F,HEX_D}}, | ||
289 | { 0 }, | ||
290 | }; | ||
291 | |||
292 | static void print_sh_insn(u32 memaddr, u16 insn) | ||
293 | { | ||
294 | int relmask = ~0; | ||
295 | int nibs[4] = { (insn >> 12) & 0xf, (insn >> 8) & 0xf, (insn >> 4) & 0xf, insn & 0xf}; | ||
296 | int lastsp; | ||
297 | struct sh_opcode_info *op = sh_table; | ||
298 | |||
299 | for (; op->name; op++) { | ||
300 | int n; | ||
301 | int imm = 0; | ||
302 | int rn = 0; | ||
303 | int rm = 0; | ||
304 | int rb = 0; | ||
305 | int disp_pc; | ||
306 | int disp_pc_addr = 0; | ||
307 | |||
308 | for (n = 0; n < 4; n++) { | ||
309 | int i = op->nibbles[n]; | ||
310 | |||
311 | if (i < 16) { | ||
312 | if (nibs[n] == i) | ||
313 | continue; | ||
314 | goto fail; | ||
315 | } | ||
316 | switch (i) { | ||
317 | case BRANCH_8: | ||
318 | imm = (nibs[2] << 4) | (nibs[3]); | ||
319 | if (imm & 0x80) | ||
320 | imm |= ~0xff; | ||
321 | imm = ((char)imm) * 2 + 4 ; | ||
322 | goto ok; | ||
323 | case BRANCH_12: | ||
324 | imm = ((nibs[1]) << 8) | (nibs[2] << 4) | (nibs[3]); | ||
325 | if (imm & 0x800) | ||
326 | imm |= ~0xfff; | ||
327 | imm = imm * 2 + 4; | ||
328 | goto ok; | ||
329 | case IMM_4: | ||
330 | imm = nibs[3]; | ||
331 | goto ok; | ||
332 | case IMM_4BY2: | ||
333 | imm = nibs[3] <<1; | ||
334 | goto ok; | ||
335 | case IMM_4BY4: | ||
336 | imm = nibs[3] <<2; | ||
337 | goto ok; | ||
338 | case IMM_8: | ||
339 | imm = (nibs[2] << 4) | nibs[3]; | ||
340 | goto ok; | ||
341 | case PCRELIMM_8BY2: | ||
342 | imm = ((nibs[2] << 4) | nibs[3]) <<1; | ||
343 | relmask = ~1; | ||
344 | goto ok; | ||
345 | case PCRELIMM_8BY4: | ||
346 | imm = ((nibs[2] << 4) | nibs[3]) <<2; | ||
347 | relmask = ~3; | ||
348 | goto ok; | ||
349 | case IMM_8BY2: | ||
350 | imm = ((nibs[2] << 4) | nibs[3]) <<1; | ||
351 | goto ok; | ||
352 | case IMM_8BY4: | ||
353 | imm = ((nibs[2] << 4) | nibs[3]) <<2; | ||
354 | goto ok; | ||
355 | case DISP_8: | ||
356 | imm = (nibs[2] << 4) | (nibs[3]); | ||
357 | goto ok; | ||
358 | case DISP_4: | ||
359 | imm = nibs[3]; | ||
360 | goto ok; | ||
361 | case REG_N: | ||
362 | rn = nibs[n]; | ||
363 | break; | ||
364 | case REG_M: | ||
365 | rm = nibs[n]; | ||
366 | break; | ||
367 | case REG_NM: | ||
368 | rn = (nibs[n] & 0xc) >> 2; | ||
369 | rm = (nibs[n] & 0x3); | ||
370 | break; | ||
371 | case REG_B: | ||
372 | rb = nibs[n] & 0x07; | ||
373 | break; | ||
374 | default: | ||
375 | return; | ||
376 | } | ||
377 | } | ||
378 | |||
379 | ok: | ||
380 | printk("%-8s ", op->name); | ||
381 | lastsp = (op->arg[0] == A_END); | ||
382 | disp_pc = 0; | ||
383 | for (n = 0; n < 6 && op->arg[n] != A_END; n++) { | ||
384 | if (n && op->arg[1] != A_END) | ||
385 | printk(", "); | ||
386 | switch (op->arg[n]) { | ||
387 | case A_IMM: | ||
388 | printk("#%d", (char)(imm)); | ||
389 | break; | ||
390 | case A_R0: | ||
391 | printk("r0"); | ||
392 | break; | ||
393 | case A_REG_N: | ||
394 | printk("r%d", rn); | ||
395 | break; | ||
396 | case A_INC_N: | ||
397 | printk("@r%d+", rn); | ||
398 | break; | ||
399 | case A_DEC_N: | ||
400 | printk("@-r%d", rn); | ||
401 | break; | ||
402 | case A_IND_N: | ||
403 | printk("@r%d", rn); | ||
404 | break; | ||
405 | case A_DISP_REG_N: | ||
406 | printk("@(%d,r%d)", imm, rn); | ||
407 | break; | ||
408 | case A_REG_M: | ||
409 | printk("r%d", rm); | ||
410 | break; | ||
411 | case A_INC_M: | ||
412 | printk("@r%d+", rm); | ||
413 | break; | ||
414 | case A_DEC_M: | ||
415 | printk("@-r%d", rm); | ||
416 | break; | ||
417 | case A_IND_M: | ||
418 | printk("@r%d", rm); | ||
419 | break; | ||
420 | case A_DISP_REG_M: | ||
421 | printk("@(%d,r%d)", imm, rm); | ||
422 | break; | ||
423 | case A_REG_B: | ||
424 | printk("r%d_bank", rb); | ||
425 | break; | ||
426 | case A_DISP_PC: | ||
427 | disp_pc = 1; | ||
428 | disp_pc_addr = imm + 4 + (memaddr & relmask); | ||
429 | printk("%08x <%pS>", disp_pc_addr, | ||
430 | (void *)disp_pc_addr); | ||
431 | break; | ||
432 | case A_IND_R0_REG_N: | ||
433 | printk("@(r0,r%d)", rn); | ||
434 | break; | ||
435 | case A_IND_R0_REG_M: | ||
436 | printk("@(r0,r%d)", rm); | ||
437 | break; | ||
438 | case A_DISP_GBR: | ||
439 | printk("@(%d,gbr)",imm); | ||
440 | break; | ||
441 | case A_R0_GBR: | ||
442 | printk("@(r0,gbr)"); | ||
443 | break; | ||
444 | case A_BDISP12: | ||
445 | case A_BDISP8: | ||
446 | printk("%08x", imm + memaddr); | ||
447 | break; | ||
448 | case A_SR: | ||
449 | printk("sr"); | ||
450 | break; | ||
451 | case A_GBR: | ||
452 | printk("gbr"); | ||
453 | break; | ||
454 | case A_VBR: | ||
455 | printk("vbr"); | ||
456 | break; | ||
457 | case A_SSR: | ||
458 | printk("ssr"); | ||
459 | break; | ||
460 | case A_SPC: | ||
461 | printk("spc"); | ||
462 | break; | ||
463 | case A_MACH: | ||
464 | printk("mach"); | ||
465 | break; | ||
466 | case A_MACL: | ||
467 | printk("macl"); | ||
468 | break; | ||
469 | case A_PR: | ||
470 | printk("pr"); | ||
471 | break; | ||
472 | case A_SGR: | ||
473 | printk("sgr"); | ||
474 | break; | ||
475 | case A_DBR: | ||
476 | printk("dbr"); | ||
477 | break; | ||
478 | case FD_REG_N: | ||
479 | if (0) | ||
480 | goto d_reg_n; | ||
481 | case F_REG_N: | ||
482 | printk("fr%d", rn); | ||
483 | break; | ||
484 | case F_REG_M: | ||
485 | printk("fr%d", rm); | ||
486 | break; | ||
487 | case DX_REG_N: | ||
488 | if (rn & 1) { | ||
489 | printk("xd%d", rn & ~1); | ||
490 | break; | ||
491 | } | ||
492 | d_reg_n: | ||
493 | case D_REG_N: | ||
494 | printk("dr%d", rn); | ||
495 | break; | ||
496 | case DX_REG_M: | ||
497 | if (rm & 1) { | ||
498 | printk("xd%d", rm & ~1); | ||
499 | break; | ||
500 | } | ||
501 | case D_REG_M: | ||
502 | printk("dr%d", rm); | ||
503 | break; | ||
504 | case FPSCR_M: | ||
505 | case FPSCR_N: | ||
506 | printk("fpscr"); | ||
507 | break; | ||
508 | case FPUL_M: | ||
509 | case FPUL_N: | ||
510 | printk("fpul"); | ||
511 | break; | ||
512 | case F_FR0: | ||
513 | printk("fr0"); | ||
514 | break; | ||
515 | case V_REG_N: | ||
516 | printk("fv%d", rn*4); | ||
517 | break; | ||
518 | case V_REG_M: | ||
519 | printk("fv%d", rm*4); | ||
520 | break; | ||
521 | case XMTRX_M4: | ||
522 | printk("xmtrx"); | ||
523 | break; | ||
524 | default: | ||
525 | return; | ||
526 | } | ||
527 | } | ||
528 | |||
529 | if (disp_pc && strcmp(op->name, "mova") != 0) { | ||
530 | u32 val; | ||
531 | |||
532 | if (relmask == ~1) | ||
533 | __get_user(val, (u16 *)disp_pc_addr); | ||
534 | else | ||
535 | __get_user(val, (u32 *)disp_pc_addr); | ||
536 | |||
537 | printk(" ! %08x <%pS>", val, (void *)val); | ||
538 | } | ||
539 | |||
540 | return; | ||
541 | fail: | ||
542 | ; | ||
543 | |||
544 | } | ||
545 | |||
546 | printk(".word 0x%x%x%x%x", nibs[0], nibs[1], nibs[2], nibs[3]); | ||
547 | } | ||
548 | |||
549 | void show_code(struct pt_regs *regs) | ||
550 | { | ||
551 | unsigned short *pc = (unsigned short *)regs->pc; | ||
552 | long i; | ||
553 | |||
554 | if (regs->pc & 0x1) | ||
555 | return; | ||
556 | |||
557 | printk("Code:\n"); | ||
558 | |||
559 | for (i = -3 ; i < 6 ; i++) { | ||
560 | unsigned short insn; | ||
561 | |||
562 | if (__get_user(insn, pc + i)) { | ||
563 | printk(" (Bad address in pc)\n"); | ||
564 | break; | ||
565 | } | ||
566 | |||
567 | printk("%s%08lx: ", (i ? " ": "->"), (unsigned long)(pc + i)); | ||
568 | print_sh_insn((unsigned long)(pc + i), insn); | ||
569 | printk("\n"); | ||
570 | } | ||
571 | |||
572 | printk("\n"); | ||
573 | } | ||