* sparc-tdep.c (sparc_gdbarch_init): Add comment explaining why
[deliverable/binutils-gdb.git] / opcodes / mcore-dis.c
CommitLineData
3442f309 1/* Disassemble Motorola M*Core instructions.
060d22b0 2 Copyright 1993, 1999, 2000 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
d7f1f2b0 16Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, 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
NC
91{
92 unsigned char ibytes[4];
93 fprintf_ftype fprintf = info->fprintf_func;
94 void * stream = info->stream;
95 unsigned short inst;
96 mcore_opcode_info * op;
97 int status;
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 {
131 case O0: break;
132 case OT: fprintf (stream, "\t%d", inst & 0x3); break;
133 case O1:
134 case JMP:
135 case JSR: fprintf (stream, "\t%s", name); break;
136 case OC: fprintf (stream, "\t%s, %s", name, crname[(inst >> 4) & 0x1F]); break;
137 case O1R1: fprintf (stream, "\t%s, r1", name); break;
97ee9b94 138 case MULSH:
3f230321
NC
139 case O2: fprintf (stream, "\t%s, %s", name, grname[(inst >> 4) & 0xF]); break;
140 case X1: fprintf (stream, "\tr1, %s", name); break;
141 case OI: fprintf (stream, "\t%s, %d", name, ((inst >> 4) & 0x1F) + 1); break;
142 case RM: fprintf (stream, "\t%s-r15, (r0)", name); break;
143 case RQ: fprintf (stream, "\tr4-r7, (%s)", name); break;
144 case OB:
145 case OBRa:
146 case OBRb:
147 case OBRc:
148 case SI:
149 case SIa:
150 case OMa:
151 case OMb:
152 case OMc: fprintf (stream, "\t%s, %d", name, (inst >> 4) & 0x1F); break;
153 case I7: fprintf (stream, "\t%s, %d", name, (inst >> 4) & 0x7F); break;
154 case LS: fprintf (stream, "\t%s, (%s, %d)", grname[(inst >> 8) & 0xF],
155 name, ((inst >> 4) & 0xF) << isiz[(inst >> 13) & 3]);
156 break;
7f6621cd 157
3f230321
NC
158 case BR:
159 {
160 long val = inst & 0x3FF;
7f6621cd 161
3f230321
NC
162 if (inst & 0x400)
163 val |= 0xFFFFFC00;
7f6621cd
KH
164
165 fprintf (stream, "\t0x%x", memaddr + 2 + (val << 1));
166
3f230321
NC
167 if (strcmp (op->name, "bsr") == 0)
168 {
c1485d85 169 /* For bsr, we'll try to get a symbol for the target. */
3f230321 170 val = memaddr + 2 + (val << 1);
7f6621cd 171
3f230321
NC
172 if (info->print_address_func && val != 0)
173 {
174 fprintf (stream, "\t// ");
175 info->print_address_func (val, info);
176 }
177 }
178 }
179 break;
7f6621cd 180
3f230321
NC
181 case BL:
182 {
183 long val;
184 val = (inst & 0x000F);
185 fprintf (stream, "\t%s, 0x%x",
7f6621cd 186 grname[(inst >> 4) & 0xF], memaddr - (val << 1));
3f230321
NC
187 }
188 break;
7f6621cd 189
3f230321
NC
190 case LR:
191 {
192 unsigned long val;
7f6621cd 193
3f230321 194 val = (memaddr + 2 + ((inst & 0xFF) << 2)) & 0xFFFFFFFC;
7f6621cd 195
3f230321 196 status = info->read_memory_func (val, ibytes, 4, info);
7f6621cd 197 if (status != 0)
3f230321
NC
198 {
199 info->memory_error_func (status, memaddr, info);
200 break;
201 }
7f6621cd 202
97ee9b94
NC
203 if (info->endian == BFD_ENDIAN_LITTLE)
204 val = (ibytes[3] << 24) | (ibytes[2] << 16)
205 | (ibytes[1] << 8) | (ibytes[0]);
206 else
3f230321
NC
207 val = (ibytes[0] << 24) | (ibytes[1] << 16)
208 | (ibytes[2] << 8) | (ibytes[3]);
7f6621cd 209
3f230321
NC
210 /* Removed [] around literal value to match ABI syntax 12/95. */
211 fprintf (stream, "\t%s, 0x%X", grname[(inst >> 8) & 0xF], val);
212
213 if (val == 0)
214 fprintf (stream, "\t// from address pool at 0x%x",
215 (memaddr + 2 + ((inst & 0xFF) << 2)) & 0xFFFFFFFC);
216 }
217 break;
7f6621cd 218
3f230321
NC
219 case LJ:
220 {
221 unsigned long val;
7f6621cd 222
3f230321 223 val = (memaddr + 2 + ((inst & 0xFF) << 2)) & 0xFFFFFFFC;
7f6621cd 224
3f230321 225 status = info->read_memory_func (val, ibytes, 4, info);
7f6621cd 226 if (status != 0)
3f230321
NC
227 {
228 info->memory_error_func (status, memaddr, info);
229 break;
230 }
231
97ee9b94
NC
232 if (info->endian == BFD_ENDIAN_LITTLE)
233 val = (ibytes[3] << 24) | (ibytes[2] << 16)
234 | (ibytes[1] << 8) | (ibytes[0]);
235 else
3f230321
NC
236 val = (ibytes[0] << 24) | (ibytes[1] << 16)
237 | (ibytes[2] << 8) | (ibytes[3]);
7f6621cd 238
3f230321
NC
239 /* Removed [] around literal value to match ABI syntax 12/95. */
240 fprintf (stream, "\t0x%X", val);
241 /* For jmpi/jsri, we'll try to get a symbol for the target. */
242 if (info->print_address_func && val != 0)
243 {
244 fprintf (stream, "\t// ");
245 info->print_address_func (val, info);
246 }
247 else
248 {
249 fprintf (stream, "\t// from address pool at 0x%x",
250 (memaddr + 2 + ((inst & 0xFF) << 2)) & 0xFFFFFFFC);
251 }
252 }
253 break;
7f6621cd 254
97ee9b94
NC
255 case OPSR:
256 {
7f6621cd
KH
257 static char *fields[] = {
258 "af", "ie", "fe", "fe,ie",
97ee9b94
NC
259 "ee", "ee,ie", "ee,fe", "ee,fe,ie"
260 };
7f6621cd 261
97ee9b94
NC
262 fprintf (stream, "\t%s", fields[inst & 0x7]);
263 }
264 break;
7f6621cd 265
3f230321 266 default:
c1485d85 267 /* If the disassembler lags the instruction set. */
3f230321
NC
268 fprintf (stream, "\tundecoded operands, inst is 0x%04x", inst);
269 break;
270 }
271 }
7f6621cd 272
c1485d85 273 /* Say how many bytes we consumed. */
3f230321
NC
274 return 2;
275}
This page took 0.126131 seconds and 4 git commands to generate.