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