1 /* Disassemble Motorolla M*Core instructions.
2 Copyright (C) 1993, 1999 Free Software Foundation, Inc.
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.
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.
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. */
22 #include "mcore-opc.h"
25 /* Mask for each mcore_opclass: */
26 static const unsigned short imsk[] =
60 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
66 #include "mcore-opc.h"
69 /* Mask for each mcore_opclass: */
70 static const unsigned short imsk[] =
104 /* OPSR */ 0xFFF8, /* psrset/psrclr */
106 /* JC */ 0, /* JC,JU,JL don't appear in object */
111 /* OB2 */ 0 /* OB2 won't appear in object. */
114 static const char * grname[] =
116 "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
117 "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15"
120 static const char X[] = "??";
122 static const char * crname[] =
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
130 static const unsigned isiz[] = { 2, 0, 1, 0 };
133 print_insn_mcore (memaddr, info)
135 struct disassemble_info * info;
137 unsigned char ibytes[4];
138 fprintf_ftype fprintf = info->fprintf_func;
139 void * stream = info->stream;
141 mcore_opcode_info * op;
144 info->bytes_per_chunk = 2;
146 status = info->read_memory_func (memaddr, ibytes, 2, info);
150 info->memory_error_func (status, memaddr, info);
154 inst = (ibytes[0] << 8) | ibytes[1];
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]))
162 fprintf (stream, ".short 0x%04x", inst);
165 const char * name = grname[inst & 0x0F];
167 fprintf (stream, "%s", op->name);
172 case OT: fprintf (stream, "\t%d", inst & 0x3); break;
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;
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]);
199 long val = inst & 0x3FF;
204 fprintf (stream, "\t0x%x", memaddr + 2 + (val<<1));
206 if (strcmp (op->name, "bsr") == 0)
208 /* for bsr, we'll try to get a symbol for the target */
209 val = memaddr + 2 + (val << 1);
211 if (info->print_address_func && val != 0)
213 fprintf (stream, "\t// ");
214 info->print_address_func (val, info);
223 val = (inst & 0x000F);
224 fprintf (stream, "\t%s, 0x%x",
225 grname[(inst >> 4) & 0xF], memaddr - (val << 1));
233 val = (memaddr + 2 + ((inst & 0xFF) << 2)) & 0xFFFFFFFC;
235 status = info->read_memory_func (val, ibytes, 4, info);
238 info->memory_error_func (status, memaddr, info);
242 val = (ibytes[0] << 24) | (ibytes[1] << 16)
243 | (ibytes[2] << 8) | (ibytes[3]);
245 /* Removed [] around literal value to match ABI syntax 12/95. */
246 fprintf (stream, "\t%s, 0x%X", grname[(inst >> 8) & 0xF], val);
249 fprintf (stream, "\t// from address pool at 0x%x",
250 (memaddr + 2 + ((inst & 0xFF) << 2)) & 0xFFFFFFFC);
258 val = (memaddr + 2 + ((inst & 0xFF) << 2)) & 0xFFFFFFFC;
260 status = info->read_memory_func (val, ibytes, 4, info);
263 info->memory_error_func (status, memaddr, info);
267 val = (ibytes[0] << 24) | (ibytes[1] << 16)
268 | (ibytes[2] << 8) | (ibytes[3]);
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)
275 fprintf (stream, "\t// ");
276 info->print_address_func (val, info);
280 fprintf (stream, "\t// from address pool at 0x%x",
281 (memaddr + 2 + ((inst & 0xFF) << 2)) & 0xFFFFFFFC);
288 static char * fields[] =
290 "af", "ie", "fe", "fe,ie",
291 "ee", "ee,ie", "ee,fe", "ee,fe,ie"
294 fprintf (stream, "\t%s", fields[inst & 0x7]);
299 /* if the disassembler lags the instruction set */
300 fprintf (stream, "\tundecoded operands, inst is 0x%04x", inst);
305 /* Say how many bytes we consumed? */