Apply patch supplied for case 102229 to implement new insns psrclr and psrset.
[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 /* OPSR */ 0xFFF8, /* psrset/psrclr */
105
106 /* JC */ 0, /* JC,JU,JL don't appear in object */
107 /* JU */ 0,
108 /* JL */ 0,
109 /* RSI */ 0,
110 /* DO21*/ 0,
111 /* OB2 */ 0 /* OB2 won't appear in object. */
112 };
113
114 static const char * grname[] =
115 {
116 "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
117 "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15"
118 };
119
120 static const char X[] = "??";
121
122 static const char * crname[] =
123 {
124 "psr", "vbr", "epsr", "fpsr", "epc", "fpc", "ss0", "ss1",
125 "ss2", "ss3", "ss4", "gcr", "gsr", X, X, X,
126 X, X, X, X, X, X, X, X,
127 X, X, X, X, X, X, X, X
128 };
129
130 static const unsigned isiz[] = { 2, 0, 1, 0 };
131
132 int
133 print_insn_mcore (memaddr, info)
134 bfd_vma memaddr;
135 struct disassemble_info * info;
136 {
137 unsigned char ibytes[4];
138 fprintf_ftype fprintf = info->fprintf_func;
139 void * stream = info->stream;
140 unsigned short inst;
141 mcore_opcode_info * op;
142 int status;
143
144 info->bytes_per_chunk = 2;
145
146 status = info->read_memory_func (memaddr, ibytes, 2, info);
147
148 if (status != 0)
149 {
150 info->memory_error_func (status, memaddr, info);
151 return -1;
152 }
153
154 inst = (ibytes[0] << 8) | ibytes[1];
155
156 /* Just a linear search of the table. */
157 for (op = mcore_table; op->name != 0; op ++)
158 if (op->inst == (inst & imsk[op->opclass]))
159 break;
160
161 if (op->name == 0)
162 fprintf (stream, ".short 0x%04x", inst);
163 else
164 {
165 const char * name = grname[inst & 0x0F];
166
167 fprintf (stream, "%s", op->name);
168
169 switch (op->opclass)
170 {
171 case O0: break;
172 case OT: fprintf (stream, "\t%d", inst & 0x3); break;
173 case O1:
174 case JMP:
175 case JSR: fprintf (stream, "\t%s", name); break;
176 case OC: fprintf (stream, "\t%s, %s", name, crname[(inst >> 4) & 0x1F]); break;
177 case O1R1: fprintf (stream, "\t%s, r1", name); break;
178 case O2: fprintf (stream, "\t%s, %s", name, grname[(inst >> 4) & 0xF]); break;
179 case X1: fprintf (stream, "\tr1, %s", name); break;
180 case OI: fprintf (stream, "\t%s, %d", name, ((inst >> 4) & 0x1F) + 1); break;
181 case RM: fprintf (stream, "\t%s-r15, (r0)", name); break;
182 case RQ: fprintf (stream, "\tr4-r7, (%s)", name); break;
183 case OB:
184 case OBRa:
185 case OBRb:
186 case OBRc:
187 case SI:
188 case SIa:
189 case OMa:
190 case OMb:
191 case OMc: fprintf (stream, "\t%s, %d", name, (inst >> 4) & 0x1F); break;
192 case I7: fprintf (stream, "\t%s, %d", name, (inst >> 4) & 0x7F); break;
193 case LS: fprintf (stream, "\t%s, (%s, %d)", grname[(inst >> 8) & 0xF],
194 name, ((inst >> 4) & 0xF) << isiz[(inst >> 13) & 3]);
195 break;
196
197 case BR:
198 {
199 long val = inst & 0x3FF;
200
201 if (inst & 0x400)
202 val |= 0xFFFFFC00;
203
204 fprintf (stream, "\t0x%x", memaddr + 2 + (val<<1));
205
206 if (strcmp (op->name, "bsr") == 0)
207 {
208 /* for bsr, we'll try to get a symbol for the target */
209 val = memaddr + 2 + (val << 1);
210
211 if (info->print_address_func && val != 0)
212 {
213 fprintf (stream, "\t// ");
214 info->print_address_func (val, info);
215 }
216 }
217 }
218 break;
219
220 case BL:
221 {
222 long val;
223 val = (inst & 0x000F);
224 fprintf (stream, "\t%s, 0x%x",
225 grname[(inst >> 4) & 0xF], memaddr - (val << 1));
226 }
227 break;
228
229 case LR:
230 {
231 unsigned long val;
232
233 val = (memaddr + 2 + ((inst & 0xFF) << 2)) & 0xFFFFFFFC;
234
235 status = info->read_memory_func (val, ibytes, 4, info);
236 if (status != 0)
237 {
238 info->memory_error_func (status, memaddr, info);
239 break;
240 }
241
242 val = (ibytes[0] << 24) | (ibytes[1] << 16)
243 | (ibytes[2] << 8) | (ibytes[3]);
244
245 /* Removed [] around literal value to match ABI syntax 12/95. */
246 fprintf (stream, "\t%s, 0x%X", grname[(inst >> 8) & 0xF], val);
247
248 if (val == 0)
249 fprintf (stream, "\t// from address pool at 0x%x",
250 (memaddr + 2 + ((inst & 0xFF) << 2)) & 0xFFFFFFFC);
251 }
252 break;
253
254 case LJ:
255 {
256 unsigned long val;
257
258 val = (memaddr + 2 + ((inst & 0xFF) << 2)) & 0xFFFFFFFC;
259
260 status = info->read_memory_func (val, ibytes, 4, info);
261 if (status != 0)
262 {
263 info->memory_error_func (status, memaddr, info);
264 break;
265 }
266
267 val = (ibytes[0] << 24) | (ibytes[1] << 16)
268 | (ibytes[2] << 8) | (ibytes[3]);
269
270 /* Removed [] around literal value to match ABI syntax 12/95. */
271 fprintf (stream, "\t0x%X", val);
272 /* For jmpi/jsri, we'll try to get a symbol for the target. */
273 if (info->print_address_func && val != 0)
274 {
275 fprintf (stream, "\t// ");
276 info->print_address_func (val, info);
277 }
278 else
279 {
280 fprintf (stream, "\t// from address pool at 0x%x",
281 (memaddr + 2 + ((inst & 0xFF) << 2)) & 0xFFFFFFFC);
282 }
283 }
284 break;
285
286 case OPSR:
287 {
288 static char * fields[] =
289 {
290 "af", "ie", "fe", "fe,ie",
291 "ee", "ee,ie", "ee,fe", "ee,fe,ie"
292 };
293
294 fprintf (stream, "\t%s", fields[inst & 0x7]);
295 }
296 break;
297
298 default:
299 /* if the disassembler lags the instruction set */
300 fprintf (stream, "\tundecoded operands, inst is 0x%04x", inst);
301 break;
302 }
303 }
304
305 /* Say how many bytes we consumed? */
306 return 2;
307 }
This page took 0.09912 seconds and 5 git commands to generate.