m10300-dis.c revision 1.1.1.1
1/* Disassemble MN10300 instructions. 2 Copyright (C) 1996, 1997 Free Software Foundation, Inc. 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 16Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ 17 18 19#include <stdio.h> 20 21#include "ansidecl.h" 22#include "opcode/mn10300.h" 23#include "dis-asm.h" 24 25static void disassemble PARAMS ((bfd_vma, struct disassemble_info *, 26 unsigned long insn, unsigned int)); 27 28int 29print_insn_mn10300 (memaddr, info) 30 bfd_vma memaddr; 31 struct disassemble_info *info; 32{ 33 int status; 34 bfd_byte buffer[4]; 35 unsigned long insn; 36 unsigned int consume; 37 38 /* First figure out how big the opcode is. */ 39 status = (*info->read_memory_func) (memaddr, buffer, 1, info); 40 if (status != 0) 41 { 42 (*info->memory_error_func) (status, memaddr, info); 43 return -1; 44 } 45 insn = *(unsigned char *) buffer; 46 47 /* These are one byte insns. */ 48 if ((insn & 0xf3) == 0x00 49 || (insn & 0xf0) == 0x10 50 || (insn & 0xfc) == 0x3c 51 || (insn & 0xf3) == 0x41 52 || (insn & 0xf3) == 0x40 53 || (insn & 0xfc) == 0x50 54 || (insn & 0xfc) == 0x54 55 || (insn & 0xf0) == 0x60 56 || (insn & 0xf0) == 0x70 57 || ((insn & 0xf0) == 0x80 58 && (insn & 0x0c) >> 2 != (insn & 0x03)) 59 || ((insn & 0xf0) == 0x90 60 && (insn & 0x0c) >> 2 != (insn & 0x03)) 61 || ((insn & 0xf0) == 0xa0 62 && (insn & 0x0c) >> 2 != (insn & 0x03)) 63 || ((insn & 0xf0) == 0xb0 64 && (insn & 0x0c) >> 2 != (insn & 0x03)) 65 || (insn & 0xff) == 0xcb 66 || (insn & 0xfc) == 0xd0 67 || (insn & 0xfc) == 0xd4 68 || (insn & 0xfc) == 0xd8 69 || (insn & 0xf0) == 0xe0) 70 { 71 consume = 1; 72 } 73 74 /* These are two byte insns. */ 75 else if ((insn & 0xf0) == 0x80 76 || (insn & 0xf0) == 0x90 77 || (insn & 0xf0) == 0xa0 78 || (insn & 0xf0) == 0xb0 79 || (insn & 0xfc) == 0x20 80 || (insn & 0xfc) == 0x28 81 || (insn & 0xf3) == 0x43 82 || (insn & 0xf3) == 0x42 83 || (insn & 0xfc) == 0x58 84 || (insn & 0xfc) == 0x5c 85 || ((insn & 0xf0) == 0xc0 86 && (insn & 0xff) != 0xcb 87 && (insn & 0xff) != 0xcc 88 && (insn & 0xff) != 0xcd) 89 || (insn & 0xff) == 0xf0 90 || (insn & 0xff) == 0xf1 91 || (insn & 0xff) == 0xf2 92 || (insn & 0xff) == 0xf3 93 || (insn & 0xff) == 0xf4 94 || (insn & 0xff) == 0xf5 95 || (insn & 0xff) == 0xf6) 96 { 97 status = (*info->read_memory_func) (memaddr, buffer, 2, info); 98 if (status != 0) 99 { 100 (*info->memory_error_func) (status, memaddr, info); 101 return -1; 102 } 103 insn = bfd_getb16 (buffer); 104 consume = 2; 105 } 106 107 /* These are three byte insns. */ 108 else if ((insn & 0xff) == 0xf8 109 || (insn & 0xff) == 0xcc 110 || (insn & 0xff) == 0xf9 111 || (insn & 0xf3) == 0x01 112 || (insn & 0xf3) == 0x02 113 || (insn & 0xf3) == 0x03 114 || (insn & 0xfc) == 0x24 115 || (insn & 0xfc) == 0x2c 116 || (insn & 0xfc) == 0x30 117 || (insn & 0xfc) == 0x34 118 || (insn & 0xfc) == 0x38 119 || (insn & 0xff) == 0xde 120 || (insn & 0xff) == 0xdf 121 || (insn & 0xff) == 0xcc) 122 { 123 status = (*info->read_memory_func) (memaddr, buffer, 2, info); 124 if (status != 0) 125 { 126 (*info->memory_error_func) (status, memaddr, info); 127 return -1; 128 } 129 insn = bfd_getb16 (buffer); 130 insn <<= 8; 131 status = (*info->read_memory_func) (memaddr + 2, buffer, 1, info); 132 if (status != 0) 133 { 134 (*info->memory_error_func) (status, memaddr, info); 135 return -1; 136 } 137 insn |= *(unsigned char *)buffer; 138 consume = 3; 139 } 140 141 /* These are four byte insns. */ 142 else if ((insn & 0xff) == 0xfa 143 || (insn & 0xff) == 0xfb) 144 { 145 status = (*info->read_memory_func) (memaddr, buffer, 4, info); 146 if (status != 0) 147 { 148 (*info->memory_error_func) (status, memaddr, info); 149 return -1; 150 } 151 insn = bfd_getb32 (buffer); 152 consume = 4; 153 } 154 155 /* These are five byte insns. */ 156 else if ((insn & 0xff) == 0xcd 157 || (insn & 0xff) == 0xdc) 158 { 159 status = (*info->read_memory_func) (memaddr, buffer, 4, info); 160 if (status != 0) 161 { 162 (*info->memory_error_func) (status, memaddr, info); 163 return -1; 164 } 165 insn = bfd_getb32 (buffer); 166 consume = 5; 167 } 168 169 /* These are six byte insns. */ 170 else if ((insn & 0xff) == 0xfd 171 || (insn & 0xff) == 0xfc) 172 { 173 status = (*info->read_memory_func) (memaddr, buffer, 4, info); 174 if (status != 0) 175 { 176 (*info->memory_error_func) (status, memaddr, info); 177 return -1; 178 } 179 180 insn = bfd_getb32 (buffer); 181 consume = 6; 182 } 183 184 /* Else its a seven byte insns (in theory). */ 185 else 186 { 187 status = (*info->read_memory_func) (memaddr, buffer, 4, info); 188 if (status != 0) 189 { 190 (*info->memory_error_func) (status, memaddr, info); 191 return -1; 192 } 193 194 insn = bfd_getb32 (buffer); 195 consume = 7; 196 } 197 198 disassemble (memaddr, info, insn, consume); 199 200 return consume; 201} 202 203static void 204disassemble (memaddr, info, insn, size) 205 bfd_vma memaddr; 206 struct disassemble_info *info; 207 unsigned long insn; 208 unsigned int size; 209{ 210 struct mn10300_opcode *op = (struct mn10300_opcode *)mn10300_opcodes; 211 const struct mn10300_operand *operand; 212 bfd_byte buffer[4]; 213 unsigned long extension = 0; 214 int status, match = 0; 215 216 /* Find the opcode. */ 217 while (op->name) 218 { 219 int mysize, extra_shift; 220 221 if (op->format == FMT_S0) 222 mysize = 1; 223 else if (op->format == FMT_S1 224 || op->format == FMT_D0) 225 mysize = 2; 226 else if (op->format == FMT_S2 227 || op->format == FMT_D1) 228 mysize = 3; 229 else if (op->format == FMT_S4) 230 mysize = 5; 231 else if (op->format == FMT_D2) 232 mysize = 4; 233 else if (op->format == FMT_D4) 234 mysize = 6; 235 else 236 mysize = 7; 237 238 if ((op->mask & insn) == op->opcode 239 && size == mysize) 240 { 241 const unsigned char *opindex_ptr; 242 unsigned int nocomma; 243 int paren = 0; 244 245 if (op->format == FMT_D1 || op->format == FMT_S1) 246 extra_shift = 8; 247 else if (op->format == FMT_D2 || op->format == FMT_D4 248 || op->format == FMT_S2 || op->format == FMT_S4 249 || op->format == FMT_S6 || op->format == FMT_D5) 250 extra_shift = 16; 251 else 252 extra_shift = 0; 253 254 if (size == 1 || size == 2) 255 { 256 extension = 0; 257 } 258 else if (size == 3 259 && (op->format == FMT_D1 260 || op->opcode == 0xdf0000 261 || op->opcode == 0xde0000)) 262 { 263 extension = 0; 264 } 265 else if (size == 3) 266 { 267 insn &= 0xff0000; 268 status = (*info->read_memory_func) (memaddr + 1, buffer, 2, info); 269 if (status != 0) 270 { 271 (*info->memory_error_func) (status, memaddr, info); 272 return; 273 } 274 275 insn |= bfd_getl16 (buffer); 276 extension = 0; 277 } 278 else if (size == 4 279 && (op->opcode == 0xfaf80000 280 || op->opcode == 0xfaf00000 281 || op->opcode == 0xfaf40000)) 282 { 283 extension = 0; 284 } 285 else if (size == 4) 286 { 287 insn &= 0xffff0000; 288 status = (*info->read_memory_func) (memaddr + 2, buffer, 2, info); 289 if (status != 0) 290 { 291 (*info->memory_error_func) (status, memaddr, info); 292 return; 293 } 294 295 insn |= bfd_getl16 (buffer); 296 extension = 0; 297 } 298 else if (size == 5 && op->opcode == 0xdc000000) 299 { 300 unsigned long temp = 0; 301 status = (*info->read_memory_func) (memaddr + 1, buffer, 4, info); 302 if (status != 0) 303 { 304 (*info->memory_error_func) (status, memaddr, info); 305 return; 306 } 307 temp |= bfd_getl32 (buffer); 308 309 insn &= 0xff000000; 310 insn |= (temp & 0xffffff00) >> 8; 311 extension = temp & 0xff; 312 } 313 else if (size == 5) 314 { 315 unsigned long temp = 0; 316 status = (*info->read_memory_func) (memaddr + 1, buffer, 2, info); 317 if (status != 0) 318 { 319 (*info->memory_error_func) (status, memaddr, info); 320 return; 321 } 322 temp |= bfd_getl16 (buffer); 323 324 insn &= 0xff0000ff; 325 insn |= temp << 8; 326 327 status = (*info->read_memory_func) (memaddr + 4, buffer, 1, info); 328 if (status != 0) 329 { 330 (*info->memory_error_func) (status, memaddr, info); 331 return; 332 } 333 extension = *(unsigned char *)buffer; 334 } 335 else if (size == 6) 336 { 337 unsigned long temp = 0; 338 status = (*info->read_memory_func) (memaddr + 2, buffer, 4, info); 339 if (status != 0) 340 { 341 (*info->memory_error_func) (status, memaddr, info); 342 return; 343 } 344 temp |= bfd_getl32 (buffer); 345 346 insn &= 0xffff0000; 347 insn |= (temp >> 16) & 0xffff; 348 extension = temp & 0xffff; 349 } 350 else if (size == 7 && op->opcode == 0xdd000000) 351 { 352 unsigned long temp = 0; 353 status = (*info->read_memory_func) (memaddr + 1, buffer, 4, info); 354 if (status != 0) 355 { 356 (*info->memory_error_func) (status, memaddr, info); 357 return; 358 } 359 temp |= bfd_getl32 (buffer); 360 361 insn &= 0xff000000; 362 insn |= (temp >> 8) & 0xffffff; 363 extension = (temp & 0xff) << 16; 364 365 status = (*info->read_memory_func) (memaddr + 5, buffer, 2, info); 366 if (status != 0) 367 { 368 (*info->memory_error_func) (status, memaddr, info); 369 return; 370 } 371 extension |= bfd_getb16 (buffer); 372 } 373 else if (size == 7) 374 { 375 unsigned long temp = 0; 376 status = (*info->read_memory_func) (memaddr + 2, buffer, 4, info); 377 if (status != 0) 378 { 379 (*info->memory_error_func) (status, memaddr, info); 380 return; 381 } 382 temp |= bfd_getl32 (buffer); 383 384 insn &= 0xffff0000; 385 insn |= (temp >> 16) & 0xffff; 386 extension = (temp & 0xffff) << 8; 387 388 status = (*info->read_memory_func) (memaddr + 6, buffer, 1, info); 389 if (status != 0) 390 { 391 (*info->memory_error_func) (status, memaddr, info); 392 return; 393 } 394 extension |= *(unsigned char *)buffer; 395 } 396 397 match = 1; 398 (*info->fprintf_func) (info->stream, "%s\t", op->name); 399 400 /* Now print the operands. */ 401 for (opindex_ptr = op->operands, nocomma = 1; 402 *opindex_ptr != 0; 403 opindex_ptr++) 404 { 405 unsigned long value; 406 407 operand = &mn10300_operands[*opindex_ptr]; 408 409 if ((operand->flags & MN10300_OPERAND_SPLIT) != 0) 410 { 411 unsigned long temp; 412 value = insn & ((1 << operand->bits) - 1); 413 value <<= (32 - operand->bits); 414 temp = extension >> operand->shift; 415 temp &= ((1 << (32 - operand->bits)) - 1); 416 value |= temp; 417 } 418 else if ((operand->flags & MN10300_OPERAND_EXTENDED) != 0) 419 { 420 value = ((extension >> (operand->shift)) 421 & ((1 << operand->bits) - 1)); 422 } 423 else 424 { 425 value = ((insn >> (operand->shift)) 426 & ((1 << operand->bits) - 1)); 427 } 428 429 if ((operand->flags & MN10300_OPERAND_SIGNED) != 0) 430 value = ((long)(value << (32 - operand->bits)) 431 >> (32 - operand->bits)); 432 433 if (!nocomma 434 && (!paren 435 || ((operand->flags & MN10300_OPERAND_PAREN) == 0))) 436 (*info->fprintf_func) (info->stream, ","); 437 438 nocomma = 0; 439 440 if ((operand->flags & MN10300_OPERAND_DREG) != 0) 441 { 442 value = ((insn >> (operand->shift + extra_shift)) 443 & ((1 << operand->bits) - 1)); 444 (*info->fprintf_func) (info->stream, "d%d", value); 445 } 446 447 else if ((operand->flags & MN10300_OPERAND_AREG) != 0) 448 { 449 value = ((insn >> (operand->shift + extra_shift)) 450 & ((1 << operand->bits) - 1)); 451 (*info->fprintf_func) (info->stream, "a%d", value); 452 } 453 454 else if ((operand->flags & MN10300_OPERAND_SP) != 0) 455 (*info->fprintf_func) (info->stream, "sp"); 456 457 else if ((operand->flags & MN10300_OPERAND_PSW) != 0) 458 (*info->fprintf_func) (info->stream, "psw"); 459 460 else if ((operand->flags & MN10300_OPERAND_MDR) != 0) 461 (*info->fprintf_func) (info->stream, "mdr"); 462 463 else if ((operand->flags & MN10300_OPERAND_PAREN) != 0) 464 { 465 if (paren) 466 (*info->fprintf_func) (info->stream, ")"); 467 else 468 { 469 (*info->fprintf_func) (info->stream, "("); 470 nocomma = 1; 471 } 472 paren = !paren; 473 } 474 475 else if ((operand->flags & MN10300_OPERAND_PCREL) != 0) 476 (*info->print_address_func) (value + memaddr, info); 477 478 else if ((operand->flags & MN10300_OPERAND_MEMADDR) != 0) 479 (*info->print_address_func) (value, info); 480 481 else if ((operand->flags & MN10300_OPERAND_REG_LIST) != 0) 482 { 483 int comma = 0; 484 485 (*info->fprintf_func) (info->stream, "["); 486 if (value & 0x80) 487 { 488 (*info->fprintf_func) (info->stream, "d2"); 489 comma = 1; 490 } 491 492 if (value & 0x40) 493 { 494 if (comma) 495 (*info->fprintf_func) (info->stream, ","); 496 (*info->fprintf_func) (info->stream, "d3"); 497 comma = 1; 498 } 499 500 if (value & 0x20) 501 { 502 if (comma) 503 (*info->fprintf_func) (info->stream, ","); 504 (*info->fprintf_func) (info->stream, "a2"); 505 comma = 1; 506 } 507 508 if (value & 0x10) 509 { 510 if (comma) 511 (*info->fprintf_func) (info->stream, ","); 512 (*info->fprintf_func) (info->stream, "a3"); 513 comma = 1; 514 } 515 516 if (value & 0x08) 517 { 518 if (comma) 519 (*info->fprintf_func) (info->stream, ","); 520 (*info->fprintf_func) (info->stream, "other"); 521 comma = 1; 522 } 523 (*info->fprintf_func) (info->stream, "]"); 524 } 525 526 else 527 (*info->fprintf_func) (info->stream, "%d", value); 528 } 529 /* All done. */ 530 break; 531 } 532 op++; 533 } 534 535 if (!match) 536 { 537 (*info->fprintf_func) (info->stream, "unknown\t0x%04x", insn); 538 } 539} 540