Linux Kernel  3.7.1
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
disassemble.c
Go to the documentation of this file.
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 {
27 
28 typedef enum {
40  X_REG_N, /* Only used for argument parsing */
41  X_REG_M, /* Only used for argument parsing */
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}},
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}},
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}},
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}},
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}},
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 }