diff options
Diffstat (limited to 'opcodes/m10200-dis.c')
-rw-r--r-- | opcodes/m10200-dis.c | 300 |
1 files changed, 146 insertions, 154 deletions
diff --git a/opcodes/m10200-dis.c b/opcodes/m10200-dis.c index 229cee9..92bc2fd 100644 --- a/opcodes/m10200-dis.c +++ b/opcodes/m10200-dis.c @@ -1,20 +1,20 @@ /* Disassemble MN10200 instructions. - Copyright 1996, 1997, 1998, 2000 Free Software Foundation, Inc. + Copyright 1996, 1997, 1998, 2000, 2005 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 -the Free Software Foundation; either version 2 of the License, or -(at your option) any later version. + 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 + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. */ + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, + MA 02110-1301, USA. */ #include <stdio.h> @@ -23,14 +23,141 @@ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. #include "dis-asm.h" #include "opintl.h" -static void disassemble PARAMS ((bfd_vma, struct disassemble_info *, - unsigned long insn, unsigned long, - unsigned int)); +static void +disassemble (bfd_vma memaddr, + struct disassemble_info *info, + unsigned long insn, + unsigned long extension, + unsigned int size) +{ + struct mn10200_opcode *op = (struct mn10200_opcode *)mn10200_opcodes; + const struct mn10200_operand *operand; + int match = 0; + + /* Find the opcode. */ + while (op->name) + { + int mysize, extra_shift; + + if (op->format == FMT_1) + mysize = 1; + else if (op->format == FMT_2 + || op->format == FMT_4) + mysize = 2; + else if (op->format == FMT_3 + || op->format == FMT_5) + mysize = 3; + else if (op->format == FMT_6) + mysize = 4; + else if (op->format == FMT_7) + mysize = 5; + else + abort (); + + if (op->format == FMT_2 || op->format == FMT_5) + extra_shift = 8; + else if (op->format == FMT_3 + || op->format == FMT_6 + || op->format == FMT_7) + extra_shift = 16; + else + extra_shift = 0; + + if ((op->mask & insn) == op->opcode + && size == (unsigned int) mysize) + { + const unsigned char *opindex_ptr; + unsigned int nocomma; + int paren = 0; + + match = 1; + (*info->fprintf_func) (info->stream, "%s\t", op->name); + + /* Now print the operands. */ + for (opindex_ptr = op->operands, nocomma = 1; + *opindex_ptr != 0; + opindex_ptr++) + { + unsigned long value; + + operand = &mn10200_operands[*opindex_ptr]; + + if ((operand->flags & MN10200_OPERAND_EXTENDED) != 0) + { + value = (insn & 0xffff) << 8; + value |= extension; + } + else + { + value = ((insn >> (operand->shift)) + & ((1L << operand->bits) - 1L)); + } + + if ((operand->flags & MN10200_OPERAND_SIGNED) != 0) + value = ((long)(value << (32 - operand->bits)) + >> (32 - operand->bits)); + + if (!nocomma + && (!paren + || ((operand->flags & MN10200_OPERAND_PAREN) == 0))) + (*info->fprintf_func) (info->stream, ","); + + nocomma = 0; + + if ((operand->flags & MN10200_OPERAND_DREG) != 0) + { + value = ((insn >> (operand->shift + extra_shift)) + & ((1 << operand->bits) - 1)); + (*info->fprintf_func) (info->stream, "d%d", value); + } + + else if ((operand->flags & MN10200_OPERAND_AREG) != 0) + { + value = ((insn >> (operand->shift + extra_shift)) + & ((1 << operand->bits) - 1)); + (*info->fprintf_func) (info->stream, "a%d", value); + } + + else if ((operand->flags & MN10200_OPERAND_PSW) != 0) + (*info->fprintf_func) (info->stream, "psw"); + + else if ((operand->flags & MN10200_OPERAND_MDR) != 0) + (*info->fprintf_func) (info->stream, "mdr"); + + else if ((operand->flags & MN10200_OPERAND_PAREN) != 0) + { + if (paren) + (*info->fprintf_func) (info->stream, ")"); + else + { + (*info->fprintf_func) (info->stream, "("); + nocomma = 1; + } + paren = !paren; + } + + else if ((operand->flags & MN10200_OPERAND_PCREL) != 0) + (*info->print_address_func) + ((value + memaddr + mysize) & 0xffffff, info); + + else if ((operand->flags & MN10200_OPERAND_MEMADDR) != 0) + (*info->print_address_func) (value, info); + + else + (*info->fprintf_func) (info->stream, "%ld", value); + } + /* All done. */ + break; + } + op++; + } + + if (!match) + (*info->fprintf_func) (info->stream, _("unknown\t0x%04lx"), insn); +} int -print_insn_mn10200 (memaddr, info) - bfd_vma memaddr; - struct disassemble_info *info; +print_insn_mn10200 (bfd_vma memaddr, struct disassemble_info *info) { int status; bfd_byte buffer[4]; @@ -204,138 +331,3 @@ print_insn_mn10200 (memaddr, info) return consume; } - -static void -disassemble (memaddr, info, insn, extension, size) - bfd_vma memaddr; - struct disassemble_info *info; - unsigned long insn; - unsigned long extension; - unsigned int size; -{ - struct mn10200_opcode *op = (struct mn10200_opcode *)mn10200_opcodes; - const struct mn10200_operand *operand; - int match = 0; - - /* Find the opcode. */ - while (op->name) - { - int mysize, extra_shift; - - if (op->format == FMT_1) - mysize = 1; - else if (op->format == FMT_2 - || op->format == FMT_4) - mysize = 2; - else if (op->format == FMT_3 - || op->format == FMT_5) - mysize = 3; - else if (op->format == FMT_6) - mysize = 4; - else if (op->format == FMT_7) - mysize = 5; - else - abort (); - - if (op->format == FMT_2 || op->format == FMT_5) - extra_shift = 8; - else if (op->format == FMT_3 - || op->format == FMT_6 - || op->format == FMT_7) - extra_shift = 16; - else - extra_shift = 0; - - if ((op->mask & insn) == op->opcode - && size == (unsigned int) mysize) - { - const unsigned char *opindex_ptr; - unsigned int nocomma; - int paren = 0; - - match = 1; - (*info->fprintf_func) (info->stream, "%s\t", op->name); - - /* Now print the operands. */ - for (opindex_ptr = op->operands, nocomma = 1; - *opindex_ptr != 0; - opindex_ptr++) - { - unsigned long value; - - operand = &mn10200_operands[*opindex_ptr]; - - if ((operand->flags & MN10200_OPERAND_EXTENDED) != 0) - { - value = (insn & 0xffff) << 8; - value |= extension; - } - else - { - value = ((insn >> (operand->shift)) - & ((1L << operand->bits) - 1L)); - } - - if ((operand->flags & MN10200_OPERAND_SIGNED) != 0) - value = ((long)(value << (32 - operand->bits)) - >> (32 - operand->bits)); - - if (!nocomma - && (!paren - || ((operand->flags & MN10200_OPERAND_PAREN) == 0))) - (*info->fprintf_func) (info->stream, ","); - - nocomma = 0; - - if ((operand->flags & MN10200_OPERAND_DREG) != 0) - { - value = ((insn >> (operand->shift + extra_shift)) - & ((1 << operand->bits) - 1)); - (*info->fprintf_func) (info->stream, "d%d", value); - } - - else if ((operand->flags & MN10200_OPERAND_AREG) != 0) - { - value = ((insn >> (operand->shift + extra_shift)) - & ((1 << operand->bits) - 1)); - (*info->fprintf_func) (info->stream, "a%d", value); - } - - else if ((operand->flags & MN10200_OPERAND_PSW) != 0) - (*info->fprintf_func) (info->stream, "psw"); - - else if ((operand->flags & MN10200_OPERAND_MDR) != 0) - (*info->fprintf_func) (info->stream, "mdr"); - - else if ((operand->flags & MN10200_OPERAND_PAREN) != 0) - { - if (paren) - (*info->fprintf_func) (info->stream, ")"); - else - { - (*info->fprintf_func) (info->stream, "("); - nocomma = 1; - } - paren = !paren; - } - - else if ((operand->flags & MN10200_OPERAND_PCREL) != 0) - (*info->print_address_func) ((value + memaddr + mysize) & 0xffffff, info); - - else if ((operand->flags & MN10200_OPERAND_MEMADDR) != 0) - (*info->print_address_func) (value, info); - - else - (*info->fprintf_func) (info->stream, "%ld", value); - } - /* All done. */ - break; - } - op++; - } - - if (!match) - { - (*info->fprintf_func) (info->stream, _("unknown\t0x%04lx"), insn); - } -} |