00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #include <stdio.h>
00020
00021 #include "sysdep.h"
00022 #include "opcode/mn10200.h"
00023 #include "dis-asm.h"
00024 #include "opintl.h"
00025
00026 static void disassemble PARAMS ((bfd_vma, struct disassemble_info *,
00027 unsigned long insn, unsigned long,
00028 unsigned int));
00029
00030 int
00031 print_insn_mn10200 (memaddr, info)
00032 bfd_vma memaddr;
00033 struct disassemble_info *info;
00034 {
00035 int status;
00036 bfd_byte buffer[4];
00037 unsigned long insn;
00038 unsigned long extension = 0;
00039 unsigned int consume;
00040
00041
00042 status = (*info->read_memory_func) (memaddr, buffer, 1, info);
00043 if (status != 0)
00044 {
00045 (*info->memory_error_func) (status, memaddr, info);
00046 return -1;
00047 }
00048
00049 insn = *(unsigned char *) buffer;
00050
00051
00052 if ((insn & 0xf0) == 0x00
00053 || (insn & 0xf0) == 0x10
00054 || (insn & 0xf0) == 0x20
00055 || (insn & 0xf0) == 0x30
00056 || ((insn & 0xf0) == 0x80
00057 && (insn & 0x0c) >> 2 != (insn & 0x03))
00058 || (insn & 0xf0) == 0x90
00059 || (insn & 0xf0) == 0xa0
00060 || (insn & 0xf0) == 0xb0
00061 || (insn & 0xff) == 0xeb
00062 || (insn & 0xff) == 0xf6
00063 || (insn & 0xff) == 0xfe
00064 || (insn & 0xff) == 0xff)
00065 {
00066 extension = 0;
00067 consume = 1;
00068 }
00069
00070
00071 else if ((insn & 0xf0) == 0x40
00072 || (insn & 0xf0) == 0x50
00073 || (insn & 0xf0) == 0x60
00074 || (insn & 0xf0) == 0x70
00075 || (insn & 0xf0) == 0x80
00076 || (insn & 0xfc) == 0xd0
00077 || (insn & 0xfc) == 0xd4
00078 || (insn & 0xfc) == 0xd8
00079 || (insn & 0xfc) == 0xe0
00080 || (insn & 0xfc) == 0xe4
00081 || (insn & 0xff) == 0xe8
00082 || (insn & 0xff) == 0xe9
00083 || (insn & 0xff) == 0xea
00084 || (insn & 0xff) == 0xf0
00085 || (insn & 0xff) == 0xf1
00086 || (insn & 0xff) == 0xf2
00087 || (insn & 0xff) == 0xf3)
00088 {
00089 status = (*info->read_memory_func) (memaddr, buffer, 2, info);
00090 if (status != 0)
00091 {
00092 (*info->memory_error_func) (status, memaddr, info);
00093 return -1;
00094 }
00095 insn = bfd_getb16 (buffer);
00096 consume = 2;
00097 }
00098
00099
00100
00101 else if ((insn & 0xf0) == 0xc0
00102 || (insn & 0xfc) == 0xdc
00103 || (insn & 0xfc) == 0xec
00104 || (insn & 0xff) == 0xf8
00105 || (insn & 0xff) == 0xf9
00106 || (insn & 0xff) == 0xfa
00107 || (insn & 0xff) == 0xfb
00108 || (insn & 0xff) == 0xfc
00109 || (insn & 0xff) == 0xfd)
00110 {
00111 status = (*info->read_memory_func) (memaddr + 1, buffer, 2, info);
00112 if (status != 0)
00113 {
00114 (*info->memory_error_func) (status, memaddr, info);
00115 return -1;
00116 }
00117 insn <<= 16;
00118 insn |= bfd_getl16 (buffer);
00119 extension = 0;
00120 consume = 3;
00121 }
00122
00123
00124 else if ((insn & 0xff) == 0xf5)
00125 {
00126 status = (*info->read_memory_func) (memaddr + 1, buffer, 2, info);
00127 if (status != 0)
00128 {
00129 (*info->memory_error_func) (status, memaddr, info);
00130 return -1;
00131 }
00132 insn <<= 16;
00133 insn |= bfd_getb16 (buffer);
00134 extension = 0;
00135 consume = 3;
00136 }
00137
00138
00139 else if ((insn & 0xff) == 0xf7)
00140 {
00141 status = (*info->read_memory_func) (memaddr, buffer, 2, info);
00142 if (status != 0)
00143 {
00144 (*info->memory_error_func) (status, memaddr, info);
00145 return -1;
00146 }
00147 insn = bfd_getb16 (buffer);
00148 insn <<= 16;
00149 status = (*info->read_memory_func) (memaddr + 2, buffer, 2, info);
00150 if (status != 0)
00151 {
00152 (*info->memory_error_func) (status, memaddr, info);
00153 return -1;
00154 }
00155 insn |= bfd_getl16 (buffer);
00156 extension = 0;
00157 consume = 4;
00158 }
00159
00160
00161 else if ((insn & 0xff) == 0xf4)
00162 {
00163 status = (*info->read_memory_func) (memaddr, buffer, 2, info);
00164 if (status != 0)
00165 {
00166 (*info->memory_error_func) (status, memaddr, info);
00167 return -1;
00168 }
00169 insn = bfd_getb16 (buffer);
00170 insn <<= 16;
00171
00172 status = (*info->read_memory_func) (memaddr + 4, buffer, 1, info);
00173 if (status != 0)
00174 {
00175 (*info->memory_error_func) (status, memaddr, info);
00176 return -1;
00177 }
00178 insn |= (*(unsigned char *)buffer << 8) & 0xff00;
00179
00180 status = (*info->read_memory_func) (memaddr + 3, buffer, 1, info);
00181 if (status != 0)
00182 {
00183 (*info->memory_error_func) (status, memaddr, info);
00184 return -1;
00185 }
00186 insn |= (*(unsigned char *)buffer) & 0xff;
00187
00188 status = (*info->read_memory_func) (memaddr + 2, buffer, 1, info);
00189 if (status != 0)
00190 {
00191 (*info->memory_error_func) (status, memaddr, info);
00192 return -1;
00193 }
00194 extension = (*(unsigned char *)buffer) & 0xff;
00195 consume = 5;
00196 }
00197 else
00198 {
00199 (*info->fprintf_func) (info->stream, _("unknown\t0x%02x"), insn);
00200 return 1;
00201 }
00202
00203 disassemble (memaddr, info, insn, extension, consume);
00204
00205 return consume;
00206 }
00207
00208 static void
00209 disassemble (memaddr, info, insn, extension, size)
00210 bfd_vma memaddr;
00211 struct disassemble_info *info;
00212 unsigned long insn;
00213 unsigned long extension;
00214 unsigned int size;
00215 {
00216 struct mn10200_opcode *op = (struct mn10200_opcode *)mn10200_opcodes;
00217 const struct mn10200_operand *operand;
00218 int match = 0;
00219
00220
00221 while (op->name)
00222 {
00223 int mysize, extra_shift;
00224
00225 if (op->format == FMT_1)
00226 mysize = 1;
00227 else if (op->format == FMT_2
00228 || op->format == FMT_4)
00229 mysize = 2;
00230 else if (op->format == FMT_3
00231 || op->format == FMT_5)
00232 mysize = 3;
00233 else if (op->format == FMT_6)
00234 mysize = 4;
00235 else if (op->format == FMT_7)
00236 mysize = 5;
00237 else
00238 abort ();
00239
00240 if (op->format == FMT_2 || op->format == FMT_5)
00241 extra_shift = 8;
00242 else if (op->format == FMT_3
00243 || op->format == FMT_6
00244 || op->format == FMT_7)
00245 extra_shift = 16;
00246 else
00247 extra_shift = 0;
00248
00249 if ((op->mask & insn) == op->opcode
00250 && size == (unsigned int) mysize)
00251 {
00252 const unsigned char *opindex_ptr;
00253 unsigned int nocomma;
00254 int paren = 0;
00255
00256 match = 1;
00257 (*info->fprintf_func) (info->stream, "%s\t", op->name);
00258
00259
00260 for (opindex_ptr = op->operands, nocomma = 1;
00261 *opindex_ptr != 0;
00262 opindex_ptr++)
00263 {
00264 unsigned long value;
00265
00266 operand = &mn10200_operands[*opindex_ptr];
00267
00268 if ((operand->flags & MN10200_OPERAND_EXTENDED) != 0)
00269 {
00270 value = (insn & 0xffff) << 8;
00271 value |= extension;
00272 }
00273 else
00274 {
00275 value = ((insn >> (operand->shift))
00276 & ((1L << operand->bits) - 1L));
00277 }
00278
00279 if ((operand->flags & MN10200_OPERAND_SIGNED) != 0)
00280 value = ((long)(value << (32 - operand->bits))
00281 >> (32 - operand->bits));
00282
00283 if (!nocomma
00284 && (!paren
00285 || ((operand->flags & MN10200_OPERAND_PAREN) == 0)))
00286 (*info->fprintf_func) (info->stream, ",");
00287
00288 nocomma = 0;
00289
00290 if ((operand->flags & MN10200_OPERAND_DREG) != 0)
00291 {
00292 value = ((insn >> (operand->shift + extra_shift))
00293 & ((1 << operand->bits) - 1));
00294 (*info->fprintf_func) (info->stream, "d%d", value);
00295 }
00296
00297 else if ((operand->flags & MN10200_OPERAND_AREG) != 0)
00298 {
00299 value = ((insn >> (operand->shift + extra_shift))
00300 & ((1 << operand->bits) - 1));
00301 (*info->fprintf_func) (info->stream, "a%d", value);
00302 }
00303
00304 else if ((operand->flags & MN10200_OPERAND_PSW) != 0)
00305 (*info->fprintf_func) (info->stream, "psw");
00306
00307 else if ((operand->flags & MN10200_OPERAND_MDR) != 0)
00308 (*info->fprintf_func) (info->stream, "mdr");
00309
00310 else if ((operand->flags & MN10200_OPERAND_PAREN) != 0)
00311 {
00312 if (paren)
00313 (*info->fprintf_func) (info->stream, ")");
00314 else
00315 {
00316 (*info->fprintf_func) (info->stream, "(");
00317 nocomma = 1;
00318 }
00319 paren = !paren;
00320 }
00321
00322 else if ((operand->flags & MN10200_OPERAND_PCREL) != 0)
00323 (*info->print_address_func) ((value + memaddr + mysize) & 0xffffff, info);
00324
00325 else if ((operand->flags & MN10200_OPERAND_MEMADDR) != 0)
00326 (*info->print_address_func) (value, info);
00327
00328 else
00329 (*info->fprintf_func) (info->stream, "%ld", value);
00330 }
00331
00332 break;
00333 }
00334 op++;
00335 }
00336
00337 if (!match)
00338 {
00339 (*info->fprintf_func) (info->stream, _("unknown\t0x%04lx"), insn);
00340 }
00341 }