00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include "sysdep.h"
00023 #include <stdio.h>
00024 #define STATIC_TABLE
00025 #define DEFINE_TABLE
00026
00027 #include "mcore-opc.h"
00028 #include "dis-asm.h"
00029
00030
00031 static const unsigned short imsk[] = {
00032 0xFFFF,
00033 0xFFFC,
00034 0xFFF0,
00035 0xFE00,
00036 0xFF00,
00037 0xFFF0,
00038 0xFE00,
00039 0xFE00,
00040
00041 0xFFF0,
00042 0xFE00,
00043 0xF800,
00044 0xF000,
00045 0xF800,
00046 0xFF00,
00047 0xF000,
00048 0xFF00,
00049
00050 0xFFF0,
00051 0xFFF0,
00052 0xFFF0,
00053 0xFFF0,
00054 0xFFF0,
00055 0xFF80,
00056 0xFF00,
00057 0xFE00,
00058
00059 0xFFF0,
00060 0xFF80,
00061 0xFF00,
00062 0xFE00,
00063
00064 0xFF00,
00065 0xFFF8,
00066
00067 0,
00068 0,
00069 0,
00070 0,
00071 0,
00072 0
00073 };
00074
00075 static const char *grname[] = {
00076 "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
00077 "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15"
00078 };
00079
00080 static const char X[] = "??";
00081
00082 static const char *crname[] = {
00083 "psr", "vbr", "epsr", "fpsr", "epc", "fpc", "ss0", "ss1",
00084 "ss2", "ss3", "ss4", "gcr", "gsr", X, X, X,
00085 X, X, X, X, X, X, X, X,
00086 X, X, X, X, X, X, X, X
00087 };
00088
00089 static const unsigned isiz[] = { 2, 0, 1, 0 };
00090
00091 int
00092 print_insn_mcore (memaddr, info)
00093 bfd_vma memaddr;
00094 struct disassemble_info *info;
00095 {
00096 unsigned char ibytes[4];
00097 fprintf_ftype fprintf = info->fprintf_func;
00098 void *stream = info->stream;
00099 unsigned short inst;
00100 const mcore_opcode_info *op;
00101 int status;
00102
00103 info->bytes_per_chunk = 2;
00104
00105 status = info->read_memory_func (memaddr, ibytes, 2, info);
00106
00107 if (status != 0)
00108 {
00109 info->memory_error_func (status, memaddr, info);
00110 return -1;
00111 }
00112
00113 if (info->endian == BFD_ENDIAN_BIG)
00114 inst = (ibytes[0] << 8) | ibytes[1];
00115 else if (info->endian == BFD_ENDIAN_LITTLE)
00116 inst = (ibytes[1] << 8) | ibytes[0];
00117 else
00118 abort ();
00119
00120
00121 for (op = mcore_table; op->name != 0; op++)
00122 if (op->inst == (inst & imsk[op->opclass]))
00123 break;
00124
00125 if (op->name == 0)
00126 fprintf (stream, ".short 0x%04x", inst);
00127 else
00128 {
00129 const char *name = grname[inst & 0x0F];
00130
00131 fprintf (stream, "%s", op->name);
00132
00133 switch (op->opclass)
00134 {
00135 case O0:
00136 break;
00137
00138 case OT:
00139 fprintf (stream, "\t%d", inst & 0x3);
00140 break;
00141
00142 case O1:
00143 case JMP:
00144 case JSR:
00145 fprintf (stream, "\t%s", name);
00146 break;
00147
00148 case OC:
00149 fprintf (stream, "\t%s, %s", name, crname[(inst >> 4) & 0x1F]);
00150 break;
00151
00152 case O1R1:
00153 fprintf (stream, "\t%s, r1", name);
00154 break;
00155
00156 case MULSH:
00157 case O2:
00158 fprintf (stream, "\t%s, %s", name, grname[(inst >> 4) & 0xF]);
00159 break;
00160
00161 case X1:
00162 fprintf (stream, "\tr1, %s", name);
00163 break;
00164
00165 case OI:
00166 fprintf (stream, "\t%s, %d", name, ((inst >> 4) & 0x1F) + 1);
00167 break;
00168
00169 case RM:
00170 fprintf (stream, "\t%s-r15, (r0)", name);
00171 break;
00172
00173 case RQ:
00174 fprintf (stream, "\tr4-r7, (%s)", name);
00175 break;
00176
00177 case OB:
00178 case OBRa:
00179 case OBRb:
00180 case OBRc:
00181 case SI:
00182 case SIa:
00183 case OMa:
00184 case OMb:
00185 case OMc:
00186 fprintf (stream, "\t%s, %d", name, (inst >> 4) & 0x1F);
00187 break;
00188
00189 case I7:
00190 fprintf (stream, "\t%s, %d", name, (inst >> 4) & 0x7F);
00191 break;
00192
00193 case LS:
00194 fprintf (stream, "\t%s, (%s, %d)", grname[(inst >> 8) & 0xF],
00195 name, ((inst >> 4) & 0xF) << isiz[(inst >> 13) & 3]);
00196 break;
00197
00198 case BR:
00199 {
00200 long val = inst & 0x3FF;
00201
00202 if (inst & 0x400)
00203 val |= 0xFFFFFC00;
00204
00205 fprintf (stream, "\t0x%x", memaddr + 2 + (val << 1));
00206
00207 if (strcmp (op->name, "bsr") == 0)
00208 {
00209
00210 val = memaddr + 2 + (val << 1);
00211
00212 if (info->print_address_func && val != 0)
00213 {
00214 fprintf (stream, "\t// ");
00215 info->print_address_func (val, info);
00216 }
00217 }
00218 }
00219 break;
00220
00221 case BL:
00222 {
00223 long val;
00224 val = (inst & 0x000F);
00225 fprintf (stream, "\t%s, 0x%x",
00226 grname[(inst >> 4) & 0xF], memaddr - (val << 1));
00227 }
00228 break;
00229
00230 case LR:
00231 {
00232 unsigned long val;
00233
00234 val = (memaddr + 2 + ((inst & 0xFF) << 2)) & 0xFFFFFFFC;
00235
00236 status = info->read_memory_func (val, ibytes, 4, info);
00237 if (status != 0)
00238 {
00239 info->memory_error_func (status, memaddr, info);
00240 break;
00241 }
00242
00243 if (info->endian == BFD_ENDIAN_LITTLE)
00244 val = (ibytes[3] << 24) | (ibytes[2] << 16)
00245 | (ibytes[1] << 8) | (ibytes[0]);
00246 else
00247 val = (ibytes[0] << 24) | (ibytes[1] << 16)
00248 | (ibytes[2] << 8) | (ibytes[3]);
00249
00250
00251 fprintf (stream, "\t%s, 0x%X", grname[(inst >> 8) & 0xF], val);
00252
00253 if (val == 0)
00254 fprintf (stream, "\t// from address pool at 0x%x",
00255 (memaddr + 2 + ((inst & 0xFF) << 2)) & 0xFFFFFFFC);
00256 }
00257 break;
00258
00259 case LJ:
00260 {
00261 unsigned long val;
00262
00263 val = (memaddr + 2 + ((inst & 0xFF) << 2)) & 0xFFFFFFFC;
00264
00265 status = info->read_memory_func (val, ibytes, 4, info);
00266 if (status != 0)
00267 {
00268 info->memory_error_func (status, memaddr, info);
00269 break;
00270 }
00271
00272 if (info->endian == BFD_ENDIAN_LITTLE)
00273 val = (ibytes[3] << 24) | (ibytes[2] << 16)
00274 | (ibytes[1] << 8) | (ibytes[0]);
00275 else
00276 val = (ibytes[0] << 24) | (ibytes[1] << 16)
00277 | (ibytes[2] << 8) | (ibytes[3]);
00278
00279
00280 fprintf (stream, "\t0x%X", val);
00281
00282 if (info->print_address_func && val != 0)
00283 {
00284 fprintf (stream, "\t// ");
00285 info->print_address_func (val, info);
00286 }
00287 else
00288 {
00289 fprintf (stream, "\t// from address pool at 0x%x",
00290 (memaddr + 2 + ((inst & 0xFF) << 2)) & 0xFFFFFFFC);
00291 }
00292 }
00293 break;
00294
00295 case OPSR:
00296 {
00297 static char *fields[] = {
00298 "af", "ie", "fe", "fe,ie",
00299 "ee", "ee,ie", "ee,fe", "ee,fe,ie"
00300 };
00301
00302 fprintf (stream, "\t%s", fields[inst & 0x7]);
00303 }
00304 break;
00305
00306 default:
00307
00308 fprintf (stream, "\tundecoded operands, inst is 0x%04x", inst);
00309 break;
00310 }
00311 }
00312
00313
00314 return 2;
00315 }