Commit 9cfc9a9b6fff9ea7a19814b4472b3cb18b7bbdcc
1 parent
edfd6da040
Exists in
master
and in
7 other branches
sh: Add a simple code dumper for SUPERH32 show_regs().
This implements a simple show_code() that is in turn plugged in to show_regs() to provide minimal code dumping at the end of the trace. Built on top of a simple instruction disassembler derived from the binutils opcode table. Signed-off-by: Paul Mundt <lethal@linux-sh.org>
Showing 4 changed files with 579 additions and 3 deletions Side-by-side Diff
arch/sh/include/asm/processor_32.h
... | ... | @@ -175,6 +175,7 @@ |
175 | 175 | |
176 | 176 | void show_trace(struct task_struct *tsk, unsigned long *sp, |
177 | 177 | struct pt_regs *regs); |
178 | +void show_code(struct pt_regs *regs); | |
178 | 179 | extern unsigned long get_wchan(struct task_struct *p); |
179 | 180 | |
180 | 181 | #define KSTK_EIP(tsk) (task_pt_regs(tsk)->pc) |
arch/sh/kernel/Makefile_32
... | ... | @@ -9,9 +9,10 @@ |
9 | 9 | CFLAGS_REMOVE_ftrace.o = -pg |
10 | 10 | endif |
11 | 11 | |
12 | -obj-y := debugtraps.o io.o io_generic.o irq.o machvec.o process_32.o \ | |
13 | - ptrace_32.o setup.o signal_32.o sys_sh.o sys_sh32.o \ | |
14 | - syscalls_32.o time_32.o topology.o traps.o traps_32.o | |
12 | +obj-y := debugtraps.o disassemble.o io.o io_generic.o irq.o \ | |
13 | + machvec.o process_32.o ptrace_32.o setup.o signal_32.o \ | |
14 | + sys_sh.o sys_sh32.o syscalls_32.o time_32.o topology.o \ | |
15 | + traps.o traps_32.o | |
15 | 16 | |
16 | 17 | obj-y += cpu/ timers/ |
17 | 18 | obj-$(CONFIG_VSYSCALL) += vsyscall/ |
arch/sh/kernel/disassemble.c
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 | +} |