X-Git-Url: http://drtracing.org/?a=blobdiff_plain;f=opcodes%2Fm10300-dis.c;h=a8d4b510dcd8884d5f081aa7dbd0967cc77f1d98;hb=6ad738c5d938c61f9b649ddd6c280e7a199048ad;hp=415bffce37df428d27ca5bdb91bcca4396903c22;hpb=ed288bb597072176e84fc8279707a3f2f475779b;p=deliverable%2Fbinutils-gdb.git diff --git a/opcodes/m10300-dis.c b/opcodes/m10300-dis.c index 415bffce37..a8d4b510dc 100644 --- a/opcodes/m10300-dis.c +++ b/opcodes/m10300-dis.c @@ -1,5 +1,5 @@ /* Disassemble MN10300 instructions. - Copyright (C) 1996, 1997, 1998 Free Software Foundation, Inc. + Copyright 1996, 1997, 1998, 1999, 2000, 2001 Free Software Foundation, Inc. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -18,15 +18,18 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include -#include "ansidecl.h" -#include "opcode/mn10300.h" +#include "sysdep.h" +#include "opcode/mn10300.h" #include "dis-asm.h" #include "opintl.h" static void disassemble PARAMS ((bfd_vma, struct disassemble_info *, unsigned long insn, unsigned int)); -int +#define HAVE_AM33 (info->mach == AM33) +#define HAVE_AM30 (info->mach == AM30) + +int print_insn_mn10300 (memaddr, info) bfd_vma memaddr; struct disassemble_info *info; @@ -100,7 +103,7 @@ print_insn_mn10300 (memaddr, info) if (status != 0) { (*info->memory_error_func) (status, memaddr, info); - return -1; + return -1; } insn = bfd_getb16 (buffer); consume = 2; @@ -108,7 +111,7 @@ print_insn_mn10300 (memaddr, info) /* These are three byte insns. */ else if ((insn & 0xff) == 0xf8 - || (insn & 0xff) == 0xcc + || (insn & 0xff) == 0xcc || (insn & 0xff) == 0xf9 || (insn & 0xf3) == 0x01 || (insn & 0xf3) == 0x02 @@ -120,6 +123,7 @@ print_insn_mn10300 (memaddr, info) || (insn & 0xfc) == 0x38 || (insn & 0xff) == 0xde || (insn & 0xff) == 0xdf + || (insn & 0xff) == 0xf9 || (insn & 0xff) == 0xcc) { status = (*info->read_memory_func) (memaddr, buffer, 2, info); @@ -136,12 +140,13 @@ print_insn_mn10300 (memaddr, info) (*info->memory_error_func) (status, memaddr, info); return -1; } - insn |= *(unsigned char *)buffer; + insn |= *(unsigned char *) buffer; consume = 3; } /* These are four byte insns. */ else if ((insn & 0xff) == 0xfa + || (insn & 0xff) == 0xf7 || (insn & 0xff) == 0xfb) { status = (*info->read_memory_func) (memaddr, buffer, 4, info); @@ -234,24 +239,37 @@ disassemble (memaddr, info, insn, size) mysize = 4; else if (op->format == FMT_D4) mysize = 6; + else if (op->format == FMT_D6) + mysize = 3; + else if (op->format == FMT_D7 || op->format == FMT_D10) + mysize = 4; + else if (op->format == FMT_D8) + mysize = 6; + else if (op->format == FMT_D9) + mysize = 7; else mysize = 7; - + if ((op->mask & insn) == op->opcode && size == (unsigned int) mysize && (op->machine == 0 - || op->machine == info->mach)) + || (op->machine == AM33 && HAVE_AM33) + || (op->machine == AM30 && HAVE_AM30))) { const unsigned char *opindex_ptr; unsigned int nocomma; int paren = 0; - + if (op->format == FMT_D1 || op->format == FMT_S1) extra_shift = 8; else if (op->format == FMT_D2 || op->format == FMT_D4 || op->format == FMT_S2 || op->format == FMT_S4 || op->format == FMT_S6 || op->format == FMT_D5) extra_shift = 16; + else if (op->format == FMT_D7 + || op->format == FMT_D8 + || op->format == FMT_D9) + extra_shift = 8; else extra_shift = 0; @@ -266,6 +284,11 @@ disassemble (memaddr, info, insn, size) { extension = 0; } + else if (size == 3 + && op->format == FMT_D6) + { + extension = 0; + } else if (size == 3) { insn &= 0xff0000; @@ -286,6 +309,12 @@ disassemble (memaddr, info, insn, size) { extension = 0; } + else if (size == 4 + && (op->format == FMT_D7 + || op->format == FMT_D10)) + { + extension = 0; + } else if (size == 4) { insn &= 0xffff0000; @@ -334,7 +363,26 @@ disassemble (memaddr, info, insn, size) (*info->memory_error_func) (status, memaddr, info); return; } - extension = *(unsigned char *)buffer; + extension = *(unsigned char *) buffer; + } + else if (size == 6 && op->format == FMT_D8) + { + insn &= 0xffffff00; + status = (*info->read_memory_func) (memaddr + 5, buffer, 1, info); + if (status != 0) + { + (*info->memory_error_func) (status, memaddr, info); + return; + } + insn |= *(unsigned char *) buffer; + + status = (*info->read_memory_func) (memaddr + 3, buffer, 2, info); + if (status != 0) + { + (*info->memory_error_func) (status, memaddr, info); + return; + } + extension = bfd_getl16 (buffer); } else if (size == 6) { @@ -351,6 +399,19 @@ disassemble (memaddr, info, insn, size) insn |= (temp >> 16) & 0xffff; extension = temp & 0xffff; } + else if (size == 7 && op->format == FMT_D9) + { + insn &= 0xffffff00; + status = (*info->read_memory_func) (memaddr + 3, buffer, 4, info); + if (status != 0) + { + (*info->memory_error_func) (status, memaddr, info); + return; + } + extension = bfd_getl32 (buffer); + insn |= (extension & 0xff000000) >> 24; + extension &= 0xffffff; + } else if (size == 7 && op->opcode == 0xdd000000) { unsigned long temp = 0; @@ -365,7 +426,7 @@ disassemble (memaddr, info, insn, size) insn &= 0xff000000; insn |= (temp >> 8) & 0xffffff; extension = (temp & 0xff) << 16; - + status = (*info->read_memory_func) (memaddr + 5, buffer, 2, info); if (status != 0) { @@ -388,14 +449,14 @@ disassemble (memaddr, info, insn, size) insn &= 0xffff0000; insn |= (temp >> 16) & 0xffff; extension = (temp & 0xffff) << 8; - + status = (*info->read_memory_func) (memaddr + 6, buffer, 1, info); if (status != 0) { (*info->memory_error_func) (status, memaddr, info); return; } - extension |= *(unsigned char *)buffer; + extension |= *(unsigned char *) buffer; } match = 1; @@ -410,6 +471,10 @@ disassemble (memaddr, info, insn, size) operand = &mn10300_operands[*opindex_ptr]; + /* If this operand is a PLUS (autoincrement), then do not emit + a comma before emitting the plus. */ + if ((operand->flags & MN10300_OPERAND_PLUS) != 0) + nocomma = 1; if ((operand->flags & MN10300_OPERAND_SPLIT) != 0) { @@ -419,6 +484,19 @@ disassemble (memaddr, info, insn, size) temp = extension >> operand->shift; temp &= ((1 << (32 - operand->bits)) - 1); value |= temp; + value = ((value ^ (((unsigned long) 1) << 31)) + - (((unsigned long) 1) << 31)); + } + else if ((operand->flags & MN10300_OPERAND_24BIT) != 0) + { + unsigned long temp; + value = insn & ((1 << operand->bits) - 1); + value <<= (24 - operand->bits); + temp = extension >> operand->shift; + temp &= ((1 << (24 - operand->bits)) - 1); + value |= temp; + if ((operand->flags & MN10300_OPERAND_SIGNED) != 0) + value = ((value & 0xffffff) ^ 0x800000) - 0x800000; } else if ((operand->flags & MN10300_OPERAND_EXTENDED) != 0) { @@ -432,9 +510,10 @@ disassemble (memaddr, info, insn, size) } if ((operand->flags & MN10300_OPERAND_SIGNED) != 0 - ) - value = ((long)(value << (32 - operand->bits)) - >> (32 - operand->bits)); + /* These are properly extended by the code above. */ + && ((operand->flags & MN10300_OPERAND_24BIT) == 0)) + value = ((value ^ (((unsigned long) 1) << (operand->bits - 1))) + - (((unsigned long) 1) << (operand->bits - 1))); if (!nocomma && (!paren @@ -442,19 +521,19 @@ disassemble (memaddr, info, insn, size) (*info->fprintf_func) (info->stream, ","); nocomma = 0; - + if ((operand->flags & MN10300_OPERAND_DREG) != 0) { value = ((insn >> (operand->shift + extra_shift)) & ((1 << operand->bits) - 1)); - (*info->fprintf_func) (info->stream, "d%d", value); + (*info->fprintf_func) (info->stream, "d%d", (int) value); } else if ((operand->flags & MN10300_OPERAND_AREG) != 0) { value = ((insn >> (operand->shift + extra_shift)) & ((1 << operand->bits) - 1)); - (*info->fprintf_func) (info->stream, "a%d", value); + (*info->fprintf_func) (info->stream, "a%d", (int) value); } else if ((operand->flags & MN10300_OPERAND_SP) != 0) @@ -466,6 +545,45 @@ disassemble (memaddr, info, insn, size) else if ((operand->flags & MN10300_OPERAND_MDR) != 0) (*info->fprintf_func) (info->stream, "mdr"); + else if ((operand->flags & MN10300_OPERAND_RREG) != 0) + { + value = ((insn >> (operand->shift + extra_shift)) + & ((1 << operand->bits) - 1)); + if (value < 8) + (*info->fprintf_func) (info->stream, "r%d", (int) value); + else if (value < 12) + (*info->fprintf_func) (info->stream, "a%d", (int) value - 8); + else + (*info->fprintf_func) (info->stream, "d%d", (int) value - 12); + } + + else if ((operand->flags & MN10300_OPERAND_XRREG) != 0) + { + value = ((insn >> (operand->shift + extra_shift)) + & ((1 << operand->bits) - 1)); + if (value == 0) + (*info->fprintf_func) (info->stream, "sp", value); + else + (*info->fprintf_func) (info->stream, "xr%d", (int) value); + } + + else if ((operand->flags & MN10300_OPERAND_USP) != 0) + (*info->fprintf_func) (info->stream, "usp"); + + else if ((operand->flags & MN10300_OPERAND_SSP) != 0) + (*info->fprintf_func) (info->stream, "ssp"); + + else if ((operand->flags & MN10300_OPERAND_MSP) != 0) + (*info->fprintf_func) (info->stream, "msp"); + + else if ((operand->flags & MN10300_OPERAND_PC) != 0) + (*info->fprintf_func) (info->stream, "pc"); + + else if ((operand->flags & MN10300_OPERAND_EPSW) != 0) + (*info->fprintf_func) (info->stream, "epsw"); + + else if ((operand->flags & MN10300_OPERAND_PLUS) != 0) + (*info->fprintf_func) (info->stream, "+"); else if ((operand->flags & MN10300_OPERAND_PAREN) != 0) { @@ -528,11 +646,32 @@ disassemble (memaddr, info, insn, size) comma = 1; } + if (value & 0x04) + { + if (comma) + (*info->fprintf_func) (info->stream, ","); + (*info->fprintf_func) (info->stream, "exreg0"); + comma = 1; + } + if (value & 0x02) + { + if (comma) + (*info->fprintf_func) (info->stream, ","); + (*info->fprintf_func) (info->stream, "exreg1"); + comma = 1; + } + if (value & 0x01) + { + if (comma) + (*info->fprintf_func) (info->stream, ","); + (*info->fprintf_func) (info->stream, "exother"); + comma = 1; + } (*info->fprintf_func) (info->stream, "]"); } - else - (*info->fprintf_func) (info->stream, "%d", value); + else + (*info->fprintf_func) (info->stream, "%ld", (long) value); } /* All done. */ break;