X-Git-Url: http://drtracing.org/?a=blobdiff_plain;f=opcodes%2Fm10300-dis.c;h=7dc899f099250207dbb79673ae279a6035d6fef4;hb=dc3febfa6ef6fa1bc6a9239f85db6faf6006655c;hp=415bffce37df428d27ca5bdb91bcca4396903c22;hpb=ed288bb597072176e84fc8279707a3f2f475779b;p=deliverable%2Fbinutils-gdb.git diff --git a/opcodes/m10300-dis.c b/opcodes/m10300-dis.c index 415bffce37..7dc899f099 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 (C) 1996, 1997, 1998, 2000 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,7 +18,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include -#include "ansidecl.h" +#include "sysdep.h" #include "opcode/mn10300.h" #include "dis-asm.h" #include "opintl.h" @@ -26,6 +26,9 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ static void disassemble PARAMS ((bfd_vma, struct disassemble_info *, unsigned long insn, unsigned int)); +#define HAVE_AM33 (info->mach == AM33) +#define HAVE_AM30 (info->mach == AM30) + int print_insn_mn10300 (memaddr, info) bfd_vma memaddr; @@ -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); @@ -142,6 +146,7 @@ print_insn_mn10300 (memaddr, info) /* 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,13 +239,22 @@ 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; @@ -252,6 +266,10 @@ disassemble (memaddr, info, insn, size) || 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; @@ -336,6 +365,25 @@ disassemble (memaddr, info, insn, size) } 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) { unsigned long temp = 0; @@ -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; @@ -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 @@ -447,14 +526,14 @@ disassemble (memaddr, info, insn, size) { 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); + (*info->fprintf_func) (info->stream, "%ld", (long)value); } /* All done. */ break;