revert previous delta
[deliverable/binutils-gdb.git] / opcodes / mcore-dis.c
1 /* Disassemble Motorolla M*Core instructions.
2 Copyright (C) 1993, 1999 Free Software Foundation, Inc.
3
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 2 of the License, or
7 (at your option) any later version.
8
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
13
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
17
18 #include <stdio.h>
19 #define STATIC_TABLE
20 #define DEFINE_TABLE
21
22 #include "mcore-opc.h"
23 #include "dis-asm.h"
24
25 /* Mask for each mcore_opclass: */
26 static const unsigned short imsk[] =
27 {
28 /* O0 */ 0xFFFF,
29 /* OT */ 0xFFFC,
30 /* O1 */ 0xFFF0,
31 /* OC */ 0xFFE0,
32 /* O2 */ 0xFF00,
33 /* X1 */ 0xFFF0,
34 /* OI */ 0xFE00,
35 /* OB */ 0xFE00,
36
37 /* OMa */ 0xFFF0,
38 /* SI */ 0xFE00,
39 /* I7 */ 0xF800,
40 /* LS */ 0xF000,
41 /* BR */ 0xF800,
42 /* BL */ 0xFF00,
43 /* LR */ 0xF000,
44 /* LJ */ 0xFF00,
45
46 /* RM */ 0xFFF0,
47 /* RQ */ 0xFFF0,
48 /* JSR */ 0xFFF0,
49 /* JMP */ 0xFFF0,
50 /* OBRa*/ 0xFFF0,
51 /* OBRb*/ 0xFF80,
52 /* OBRc*/ 0xFF00,
53 /* OBR2*/ 0xFE00,
54
55 /* O1R1*/ 0xFFF0,
56 /* OMb */ 0xFF80,
57 /* OMc */ 0xFF00,
58 /* SIa */ 0xFE00,
59
60 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
61
62 #include <stdio.h>
63 #define STATIC_TABLE
64 #define DEFINE_TABLE
65
66 #include "mcore-opc.h"
67 #include "dis-asm.h"
68
69 /* Mask for each mcore_opclass: */
70 static const unsigned short imsk[] =
71 {
72 /* O0 */ 0xFFFF,
73 /* OT */ 0xFFFC,
74 /* O1 */ 0xFFF0,
75 /* OC */ 0xFFE0,
76 /* O2 */ 0xFF00,
77 /* X1 */ 0xFFF0,
78 /* OI */ 0xFE00,
79 /* OB */ 0xFE00,
80
81 /* OMa */ 0xFFF0,
82 /* SI */ 0xFE00,
83 /* I7 */ 0xF800,
84 /* LS */ 0xF000,
85 /* BR */ 0xF800,
86 /* BL */ 0xFF00,
87 /* LR */ 0xF000,
88 /* LJ */ 0xFF00,
89
90 /* RM */ 0xFFF0,
91 /* RQ */ 0xFFF0,
92 /* JSR */ 0xFFF0,
93 /* JMP */ 0xFFF0,
94 /* OBRa*/ 0xFFF0,
95 /* OBRb*/ 0xFF80,
96 /* OBRc*/ 0xFF00,
97 /* OBR2*/ 0xFE00,
98
99 /* O1R1*/ 0xFFF0,
100 /* OMb */ 0xFF80,
101 /* OMc */ 0xFF00,
102 /* SIa */ 0xFE00,
103
104 /* JC */ 0, /* JC,JU,JL don't appear in object */
105 /* JU */ 0,
106 /* JL */ 0,
107 /* RSI */ 0,
108 /* DO21*/ 0,
109 /* OB2 */ 0 /* OB2 won't appear in object. */
110 };
111
112 static const char * grname[] =
113 {
114 "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
115 "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15"
116 };
117
118 static const char X[] = "??";
119
120 static const char * crname[] =
121 {
122 "psr", "vbr", "epsr", "fpsr", "epc", "fpc", "ss0", "ss1",
123 "ss2", "ss3", "ss4", "gcr", "gsr", X, X, X,
124 X, X, X, X, X, X, X, X,
125 X, X, X, X, X, X, X, X
126 };
127
128 static const unsigned isiz[] = { 2, 0, 1, 0 };
129
130 int
131 print_insn_mcore (memaddr, info)
132 bfd_vma memaddr;
133 struct disassemble_info * info;
134 {
135 unsigned char ibytes[4];
136 fprintf_ftype fprintf = info->fprintf_func;
137 void * stream = info->stream;
138 unsigned short inst;
139 mcore_opcode_info * op;
140 int status;
141
142 info->bytes_per_chunk = 2;
143
144 status = info->read_memory_func (memaddr, ibytes, 2, info);
145
146 if (status != 0)
147 {
148 info->memory_error_func (status, memaddr, info);
149 return -1;
150 }
151
152 inst = (ibytes[0] << 8) | ibytes[1];
153
154 /* Just a linear search of the table. */
155 for (op = mcore_table; op->name != 0; op ++)
156 if (op->inst == (inst & imsk[op->opclass]))
157 break;
158
159 if (op->name == 0)
160 fprintf (stream, ".short 0x%04x", inst);
161 else
162 {
163 const char * name = grname[inst & 0x0F];
164
165 fprintf (stream, "%s", op->name);
166
167 switch (op->opclass)
168 {
169 case O0: break;
170 case OT: fprintf (stream, "\t%d", inst & 0x3); break;
171 case O1:
172 case JMP:
173 case JSR: fprintf (stream, "\t%s", name); break;
174 case OC: fprintf (stream, "\t%s, %s", name, crname[(inst >> 4) & 0x1F]); break;
175 case O1R1: fprintf (stream, "\t%s, r1", name); break;
176 case O2: fprintf (stream, "\t%s, %s", name, grname[(inst >> 4) & 0xF]); break;
177 case X1: fprintf (stream, "\tr1, %s", name); break;
178 case OI: fprintf (stream, "\t%s, %d", name, ((inst >> 4) & 0x1F) + 1); break;
179 case RM: fprintf (stream, "\t%s-r15, (r0)", name); break;
180 case RQ: fprintf (stream, "\tr4-r7, (%s)", name); break;
181 case OB:
182 case OBRa:
183 case OBRb:
184 case OBRc:
185 case SI:
186 case SIa:
187 case OMa:
188 case OMb:
189 case OMc: fprintf (stream, "\t%s, %d", name, (inst >> 4) & 0x1F); break;
190 case I7: fprintf (stream, "\t%s, %d", name, (inst >> 4) & 0x7F); break;
191 case LS: fprintf (stream, "\t%s, (%s, %d)", grname[(inst >> 8) & 0xF],
192 name, ((inst >> 4) & 0xF) << isiz[(inst >> 13) & 3]);
193 break;
194
195 case BR:
196 {
197 long val = inst & 0x3FF;
198
199 if (inst & 0x400)
200 val |= 0xFFFFFC00;
201
202 fprintf (stream, "\t0x%x", memaddr + 2 + (val<<1));
203
204 if (strcmp (op->name, "bsr") == 0)
205 {
206 /* for bsr, we'll try to get a symbol for the target */
207 val = memaddr + 2 + (val << 1);
208
209 if (info->print_address_func && val != 0)
210 {
211 fprintf (stream, "\t// ");
212 info->print_address_func (val, info);
213 }
214 }
215 }
216 break;
217
218 case BL:
219 {
220 long val;
221 val = (inst & 0x000F);
222 fprintf (stream, "\t%s, 0x%x",
223 grname[(inst >> 4) & 0xF], memaddr - (val << 1));
224 }
225 break;
226
227 case LR:
228 {
229 unsigned long val;
230
231 val = (memaddr + 2 + ((inst & 0xFF) << 2)) & 0xFFFFFFFC;
232
233 status = info->read_memory_func (val, ibytes, 4, info);
234 if (status != 0)
235 {
236 info->memory_error_func (status, memaddr, info);
237 break;
238 }
239
240 val = (ibytes[0] << 24) | (ibytes[1] << 16)
241 | (ibytes[2] << 8) | (ibytes[3]);
242
243 /* Removed [] around literal value to match ABI syntax 12/95. */
244 fprintf (stream, "\t%s, 0x%X", grname[(inst >> 8) & 0xF], val);
245
246 if (val == 0)
247 fprintf (stream, "\t// from address pool at 0x%x",
248 (memaddr + 2 + ((inst & 0xFF) << 2)) & 0xFFFFFFFC);
249 }
250 break;
251
252 case LJ:
253 {
254 unsigned long val;
255
256 val = (memaddr + 2 + ((inst & 0xFF) << 2)) & 0xFFFFFFFC;
257
258 status = info->read_memory_func (val, ibytes, 4, info);
259 if (status != 0)
260 {
261 info->memory_error_func (status, memaddr, info);
262 break;
263 }
264
265 val = (ibytes[0] << 24) | (ibytes[1] << 16)
266 | (ibytes[2] << 8) | (ibytes[3]);
267
268 /* Removed [] around literal value to match ABI syntax 12/95. */
269 fprintf (stream, "\t0x%X", val);
270 /* For jmpi/jsri, we'll try to get a symbol for the target. */
271 if (info->print_address_func && val != 0)
272 {
273 fprintf (stream, "\t// ");
274 info->print_address_func (val, info);
275 }
276 else
277 {
278 fprintf (stream, "\t// from address pool at 0x%x",
279 (memaddr + 2 + ((inst & 0xFF) << 2)) & 0xFFFFFFFC);
280 }
281 }
282 break;
283
284 default:
285 /* if the disassembler lags the instruction set */
286 fprintf (stream, "\tundecoded operands, inst is 0x%04x", inst);
287 break;
288 }
289 }
290
291 /* Say how many bytes we consumed? */
292 return 2;
293 }
This page took 0.090293 seconds and 5 git commands to generate.