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