ChangeLog rotatation and copyright year update
[deliverable/binutils-gdb.git] / opcodes / mcore-dis.c
CommitLineData
3442f309 1/* Disassemble Motorola M*Core instructions.
b90efa5b 2 Copyright (C) 1993-2015 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 95 unsigned char ibytes[4];
91d6fa6a 96 fprintf_ftype print_func = info->fprintf_func;
6a51a8a8
AM
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)
91d6fa6a 125 (*print_func) (stream, ".short 0x%04x", inst);
3f230321
NC
126 else
127 {
7f6621cd
KH
128 const char *name = grname[inst & 0x0F];
129
91d6fa6a 130 (*print_func) (stream, "%s", op->name);
7f6621cd 131
3f230321
NC
132 switch (op->opclass)
133 {
6a51a8a8
AM
134 case O0:
135 break;
136
137 case OT:
91d6fa6a 138 (*print_func) (stream, "\t%d", inst & 0x3);
6a51a8a8
AM
139 break;
140
3f230321
NC
141 case O1:
142 case JMP:
6a51a8a8 143 case JSR:
91d6fa6a 144 (*print_func) (stream, "\t%s", name);
6a51a8a8
AM
145 break;
146
147 case OC:
91d6fa6a 148 (*print_func) (stream, "\t%s, %s", name, crname[(inst >> 4) & 0x1F]);
6a51a8a8
AM
149 break;
150
151 case O1R1:
91d6fa6a 152 (*print_func) (stream, "\t%s, r1", name);
6a51a8a8
AM
153 break;
154
97ee9b94 155 case MULSH:
6a51a8a8 156 case O2:
91d6fa6a 157 (*print_func) (stream, "\t%s, %s", name, grname[(inst >> 4) & 0xF]);
6a51a8a8
AM
158 break;
159
160 case X1:
91d6fa6a 161 (*print_func) (stream, "\tr1, %s", name);
6a51a8a8
AM
162 break;
163
164 case OI:
91d6fa6a 165 (*print_func) (stream, "\t%s, %d", name, ((inst >> 4) & 0x1F) + 1);
6a51a8a8
AM
166 break;
167
168 case RM:
91d6fa6a 169 (*print_func) (stream, "\t%s-r15, (r0)", name);
6a51a8a8
AM
170 break;
171
172 case RQ:
91d6fa6a 173 (*print_func) (stream, "\tr4-r7, (%s)", name);
6a51a8a8
AM
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 184 case OMc:
91d6fa6a 185 (*print_func) (stream, "\t%s, %d", name, (inst >> 4) & 0x1F);
6a51a8a8
AM
186 break;
187
188 case I7:
91d6fa6a 189 (*print_func) (stream, "\t%s, %d", name, (inst >> 4) & 0x7F);
6a51a8a8
AM
190 break;
191
192 case LS:
91d6fa6a
NC
193 (*print_func) (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
91d6fa6a 204 (*print_func) (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 {
91d6fa6a 213 (*print_func) (stream, "\t// ");
3f230321
NC
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);
91d6fa6a
NC
224 (*print_func) (stream, "\t%s, 0x%lx",
225 grname[(inst >> 4) & 0xF],
226 (long) (memaddr - (val << 1)));
3f230321
NC
227 }
228 break;
7f6621cd 229
3f230321
NC
230 case LR:
231 {
232 unsigned long val;
7f6621cd 233
3f230321 234 val = (memaddr + 2 + ((inst & 0xFF) << 2)) & 0xFFFFFFFC;
7f6621cd 235
3f230321 236 status = info->read_memory_func (val, ibytes, 4, info);
7f6621cd 237 if (status != 0)
3f230321
NC
238 {
239 info->memory_error_func (status, memaddr, info);
240 break;
241 }
7f6621cd 242
97ee9b94
NC
243 if (info->endian == BFD_ENDIAN_LITTLE)
244 val = (ibytes[3] << 24) | (ibytes[2] << 16)
245 | (ibytes[1] << 8) | (ibytes[0]);
246 else
3f230321
NC
247 val = (ibytes[0] << 24) | (ibytes[1] << 16)
248 | (ibytes[2] << 8) | (ibytes[3]);
7f6621cd 249
3f230321 250 /* Removed [] around literal value to match ABI syntax 12/95. */
91d6fa6a 251 (*print_func) (stream, "\t%s, 0x%lX", grname[(inst >> 8) & 0xF], val);
3f230321
NC
252
253 if (val == 0)
91d6fa6a
NC
254 (*print_func) (stream, "\t// from address pool at 0x%lx",
255 (long) (memaddr + 2
256 + ((inst & 0xFF) << 2)) & 0xFFFFFFFC);
3f230321
NC
257 }
258 break;
7f6621cd 259
3f230321
NC
260 case LJ:
261 {
262 unsigned long val;
7f6621cd 263
3f230321 264 val = (memaddr + 2 + ((inst & 0xFF) << 2)) & 0xFFFFFFFC;
7f6621cd 265
3f230321 266 status = info->read_memory_func (val, ibytes, 4, info);
7f6621cd 267 if (status != 0)
3f230321
NC
268 {
269 info->memory_error_func (status, memaddr, info);
270 break;
271 }
272
97ee9b94
NC
273 if (info->endian == BFD_ENDIAN_LITTLE)
274 val = (ibytes[3] << 24) | (ibytes[2] << 16)
275 | (ibytes[1] << 8) | (ibytes[0]);
276 else
3f230321
NC
277 val = (ibytes[0] << 24) | (ibytes[1] << 16)
278 | (ibytes[2] << 8) | (ibytes[3]);
7f6621cd 279
3f230321 280 /* Removed [] around literal value to match ABI syntax 12/95. */
91d6fa6a 281 (*print_func) (stream, "\t0x%lX", val);
3f230321
NC
282 /* For jmpi/jsri, we'll try to get a symbol for the target. */
283 if (info->print_address_func && val != 0)
284 {
91d6fa6a 285 (*print_func) (stream, "\t// ");
3f230321
NC
286 info->print_address_func (val, info);
287 }
288 else
289 {
91d6fa6a
NC
290 (*print_func) (stream, "\t// from address pool at 0x%lx",
291 (long) (memaddr + 2
292 + ((inst & 0xFF) << 2)) & 0xFFFFFFFC);
3f230321
NC
293 }
294 }
295 break;
7f6621cd 296
97ee9b94
NC
297 case OPSR:
298 {
7f6621cd
KH
299 static char *fields[] = {
300 "af", "ie", "fe", "fe,ie",
97ee9b94
NC
301 "ee", "ee,ie", "ee,fe", "ee,fe,ie"
302 };
7f6621cd 303
91d6fa6a 304 (*print_func) (stream, "\t%s", fields[inst & 0x7]);
97ee9b94
NC
305 }
306 break;
7f6621cd 307
3f230321 308 default:
c1485d85 309 /* If the disassembler lags the instruction set. */
91d6fa6a 310 (*print_func) (stream, "\tundecoded operands, inst is 0x%04x", inst);
3f230321
NC
311 break;
312 }
313 }
7f6621cd 314
c1485d85 315 /* Say how many bytes we consumed. */
3f230321
NC
316 return 2;
317}
This page took 0.647038 seconds and 4 git commands to generate.