X-Git-Url: http://git.efficios.com/?a=blobdiff_plain;f=opcodes%2Fh8300-dis.c;h=c99b9f349897a2f1a2378e8aa830b71b0072202c;hb=61b3df8f5b7c75e51a4fe45bc7e479b4b482a1cd;hp=299267f4605586df52f279ce1123da05da97987f;hpb=20dc5b5ae3df799978612c86b73b347f56e7fe69;p=deliverable%2Fbinutils-gdb.git diff --git a/opcodes/h8300-dis.c b/opcodes/h8300-dis.c index 299267f460..c99b9f3498 100644 --- a/opcodes/h8300-dis.c +++ b/opcodes/h8300-dis.c @@ -1,27 +1,29 @@ /* Disassemble h8300 instructions. - Copyright 1993, 1994, 1996, 1998, 2000, 2001, 2002, 2003 - Free Software Foundation, Inc. + Copyright (C) 1993-2019 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 file is part of the GNU opcodes library. -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. + This library 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 3, or (at your option) + any later version. -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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ + It 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. */ #define DEFINE_TABLE #include "sysdep.h" #define h8_opcodes h8ops #include "opcode/h8300.h" -#include "dis-asm.h" +#include "disassemble.h" #include "opintl.h" #include "libiberty.h" @@ -33,42 +35,11 @@ struct h8_instruction struct h8_instruction *h8_instructions; -static void bfd_h8_disassemble_init PARAMS ((void)); -static void print_one_arg PARAMS ((disassemble_info *, bfd_vma, op_type, - int, int, int, int, const char **, int)); -static unsigned int bfd_h8_disassemble PARAMS ((bfd_vma, - disassemble_info *, - int)); -static void extract_immediate PARAMS ((FILE *, - op_type, int, - unsigned char *, - int *, int *, - const struct h8_opcode *)); - -static void print_colon_thingie PARAMS ((op_type *)); - -static void -print_colon_thingie (op_type *nib) -{ - switch (*nib & SIZE) { - case L_2: fprintf (stdout, "2"); break; - case L_3: - case L_3NZ: fprintf (stdout, "3"); break; - case L_4: fprintf (stdout, "4"); break; - case L_5: fprintf (stdout, "5"); break; - case L_8: fprintf (stdout, "8"); break; - case L_16: - case L_16U: fprintf (stdout, "16"); break; - case L_24: fprintf (stdout, "24"); break; - case L_32: fprintf (stdout, "32"); break; - } -} - /* Run through the opcodes and sort them into order to make them easy to disassemble. */ static void -bfd_h8_disassemble_init () +bfd_h8_disassemble_init (void) { unsigned int i; unsigned int nopcodes; @@ -77,24 +48,10 @@ bfd_h8_disassemble_init () nopcodes = sizeof (h8_opcodes) / sizeof (struct h8_opcode); - h8_instructions = (struct h8_instruction *) - xmalloc (nopcodes * sizeof (struct h8_instruction)); + h8_instructions = xmalloc (nopcodes * sizeof (struct h8_instruction)); for (p = h8_opcodes, pi = h8_instructions; p->name; p++, pi++) { - int n1 = 0; - int n2 = 0; - - if ((int) p->data.nib[0] < 16) - n1 = (int) p->data.nib[0]; - else - n1 = 0; - - if ((int) p->data.nib[1] < 16) - n2 = (int) p->data.nib[1]; - else - n2 = 0; - /* Just make sure there are an even number of nibbles in it, and that the count is the same as the length. */ for (i = 0; p->data.nib[i] != (op_type) E; i++) @@ -102,7 +59,8 @@ bfd_h8_disassemble_init () if (i & 1) { - fprintf (stderr, "Internal error, h8_disassemble_init.\n"); + /* xgettext:c-format */ + opcodes_error_handler (_("internal error, h8_disassemble_init")); abort (); } @@ -116,13 +74,13 @@ bfd_h8_disassemble_init () } static void -extract_immediate (stream, looking_for, thisnib, data, cst, len, q) - FILE *stream; - op_type looking_for; - int thisnib; - unsigned char *data; - int *cst, *len; - const struct h8_opcode *q; +extract_immediate (FILE *stream, + op_type looking_for, + int thisnib, + unsigned char *data, + int *cst, + int *len, + const struct h8_opcode *q) { switch (looking_for & SIZE) { @@ -133,35 +91,37 @@ extract_immediate (stream, looking_for, thisnib, data, cst, len, q) /* DISP2 special treatment. */ if ((looking_for & MODE) == DISP) { - if (OP_KIND (q->how) == O_MOVAB || - OP_KIND (q->how) == O_MOVAW || - OP_KIND (q->how) == O_MOVAL) + if (OP_KIND (q->how) == O_MOVAB + || OP_KIND (q->how) == O_MOVAW + || OP_KIND (q->how) == O_MOVAL) { /* Handling for mova insn. */ - switch (q->args.nib[0] & MODE) { - case INDEXB: - default: - break; - case INDEXW: - *cst *= 2; - break; - case INDEXL: - *cst *= 4; - break; - } + switch (q->args.nib[0] & MODE) + { + case INDEXB: + default: + break; + case INDEXW: + *cst *= 2; + break; + case INDEXL: + *cst *= 4; + break; + } } else { /* Handling for non-mova insn. */ - switch (OP_SIZE (q->how)) { - default: break; - case SW: - *cst *= 2; - break; - case SL: - *cst *= 4; - break; - } + switch (OP_SIZE (q->how)) + { + default: break; + case SW: + *cst *= 2; + break; + case SL: + *cst *= 4; + break; + } } } break; @@ -175,12 +135,13 @@ extract_immediate (stream, looking_for, thisnib, data, cst, len, q) *cst = (data[0] << 8) + data [1]; #if 0 if ((looking_for & SIZE) == L_16) - *cst = (short) *cst; /* sign extend */ + *cst = (short) *cst; /* Sign extend. */ #endif break; case L_32: *len = 32; - *cst = (data[0] << 24) + (data[1] << 16) + (data[2] << 8) + data[3]; + *cst = (((unsigned) data[0] << 24) + (data[1] << 16) + + (data[2] << 8) + data[3]); break; default: *len = 0; @@ -211,31 +172,25 @@ static const char *cregnames[] = }; static void -print_one_arg (info, addr, x, cst, cstlen, rdisp_n, rn, pregnames, len) - disassemble_info *info; - bfd_vma addr; - op_type x; - int cst, cstlen, rdisp_n, rn; - const char **pregnames; - int len; +print_one_arg (disassemble_info *info, + bfd_vma addr, + op_type x, + int cst, + int cstlen, + int rdisp_n, + int rn, + const char **pregnames, + int len) { - void *stream = info->stream; + void * stream = info->stream; fprintf_ftype outfn = info->fprintf_func; - if ((x & SIZE) == L_3 || - (x & SIZE) == L_3NZ) - { - outfn (stream, "#0x%x", (unsigned) cst); - } + if ((x & SIZE) == L_3 || (x & SIZE) == L_3NZ) + outfn (stream, "#0x%x", (unsigned) cst); else if ((x & MODE) == IMM) - { - outfn (stream, "#0x%x", (unsigned) cst); - } - else if ((x & MODE) == DBIT || - (x & MODE) == KBIT) - { - outfn (stream, "#%d", (unsigned) cst); - } + outfn (stream, "#0x%x", (unsigned) cst); + else if ((x & MODE) == DBIT || (x & MODE) == KBIT) + outfn (stream, "#%d", (unsigned) cst); else if ((x & MODE) == CONST_2) outfn (stream, "#2"); else if ((x & MODE) == CONST_4) @@ -281,33 +236,26 @@ print_one_arg (info, addr, x, cst, cstlen, rdisp_n, rn, pregnames, len) } } else if ((x & MODE) == POSTINC) - { - outfn (stream, "@%s+", pregnames[rn]); - } + outfn (stream, "@%s+", pregnames[rn]); + else if ((x & MODE) == POSTDEC) - { - outfn (stream, "@%s-", pregnames[rn]); - } + outfn (stream, "@%s-", pregnames[rn]); + else if ((x & MODE) == PREINC) - { - outfn (stream, "@+%s", pregnames[rn]); - } + outfn (stream, "@+%s", pregnames[rn]); + else if ((x & MODE) == PREDEC) - { - outfn (stream, "@-%s", pregnames[rn]); - } + outfn (stream, "@-%s", pregnames[rn]); + else if ((x & MODE) == IND) - { - outfn (stream, "@%s", pregnames[rn]); - } + outfn (stream, "@%s", pregnames[rn]); + else if ((x & MODE) == ABS || (x & ABSJMP)) - { - outfn (stream, "@0x%x:%d", (unsigned) cst, cstlen); - } + outfn (stream, "@0x%x:%d", (unsigned) cst, cstlen); + else if ((x & MODE) == MEMIND) - { - outfn (stream, "@@%d (0x%x)", cst, cst); - } + outfn (stream, "@@%d (0x%x)", cst, cst); + else if ((x & MODE) == VECIND) { /* FIXME Multiplier should be 2 or 4, depending on processor mode, @@ -321,67 +269,54 @@ print_one_arg (info, addr, x, cst, cstlen, rdisp_n, rn, pregnames, len) if ((x & SIZE) == L_16 || (x & SIZE) == L_16U) { - outfn (stream, ".%s%d (0x%x)", + outfn (stream, ".%s%d (0x%lx)", (short) cst > 0 ? "+" : "", - (short) cst, - addr + (short) cst + len); + (short) cst, + (long)(addr + (short) cst + len)); } else { - outfn (stream, ".%s%d (0x%x)", + outfn (stream, ".%s%d (0x%lx)", (char) cst > 0 ? "+" : "", - (char) cst, - addr + (char) cst + len); + (char) cst, + (long)(addr + (char) cst + len)); } } else if ((x & MODE) == DISP) - { - outfn (stream, "@(0x%x:%d,%s)", cst, cstlen, - pregnames[rdisp_n]); - } + outfn (stream, "@(0x%x:%d,%s)", cst, cstlen, pregnames[rdisp_n]); + else if ((x & MODE) == INDEXB) - { - /* Always take low half of reg. */ - outfn (stream, "@(0x%x:%d,%s.b)", cst, cstlen, - regnames[rdisp_n < 8 ? rdisp_n + 8 : rdisp_n]); - } + /* Always take low half of reg. */ + outfn (stream, "@(0x%x:%d,%s.b)", cst, cstlen, + regnames[rdisp_n < 8 ? rdisp_n + 8 : rdisp_n]); + else if ((x & MODE) == INDEXW) - { - /* Always take low half of reg. */ - outfn (stream, "@(0x%x:%d,%s.w)", cst, cstlen, - wregnames[rdisp_n < 8 ? rdisp_n : rdisp_n - 8]); - } + /* Always take low half of reg. */ + outfn (stream, "@(0x%x:%d,%s.w)", cst, cstlen, + wregnames[rdisp_n < 8 ? rdisp_n : rdisp_n - 8]); + else if ((x & MODE) == INDEXL) - { - outfn (stream, "@(0x%x:%d,%s.l)", cst, cstlen, - lregnames[rdisp_n]); - } + outfn (stream, "@(0x%x:%d,%s.l)", cst, cstlen, lregnames[rdisp_n]); + else if (x & CTRL) - { - outfn (stream, cregnames[rn]); - } + outfn (stream, "%s", cregnames[rn]); + else if ((x & MODE) == CCR) - { - outfn (stream, "ccr"); - } + outfn (stream, "ccr"); + else if ((x & MODE) == EXR) - { - outfn (stream, "exr"); - } + outfn (stream, "exr"); + else if ((x & MODE) == MACREG) - { - outfn (stream, "mac%c", cst ? 'l' : 'h'); - } + outfn (stream, "mac%c", cst ? 'l' : 'h'); + else /* xgettext:c-format */ outfn (stream, _("Hmmmm 0x%x"), x); } static unsigned int -bfd_h8_disassemble (addr, info, mach) - bfd_vma addr; - disassemble_info *info; - int mach; +bfd_h8_disassemble (bfd_vma addr, disassemble_info *info, int mach) { /* Find the first entry in the table for this opcode. */ int regno[3] = { 0, 0, 0 }; @@ -417,7 +352,7 @@ bfd_h8_disassemble (addr, info, mach) for (qi = h8_instructions; qi->opcode->name; qi++) { const struct h8_opcode *q = qi->opcode; - op_type *nib = q->data.nib; + const op_type *nib = q->data.nib; unsigned int len = 0; while (1) @@ -520,50 +455,50 @@ bfd_h8_disassemble (addr, info, mach) cst[opnr] = (thisnib & 0x8) ? 2 : 1; } - else if ((looking_for & MODE) == DISP || - (looking_for & MODE) == ABS || - (looking_for & MODE) == PCREL || - (looking_for & MODE) == INDEXB || - (looking_for & MODE) == INDEXW || - (looking_for & MODE) == INDEXL) + else if ((looking_for & MODE) == DISP + || (looking_for & MODE) == ABS + || (looking_for & MODE) == PCREL + || (looking_for & MODE) == INDEXB + || (looking_for & MODE) == INDEXW + || (looking_for & MODE) == INDEXL) { - extract_immediate (stream, looking_for, thisnib, - data + len / 2, cst + opnr, + extract_immediate (stream, looking_for, thisnib, + data + len / 2, cst + opnr, cstlen + opnr, q); /* Even address == bra, odd == bra/s. */ if (q->how == O (O_BRAS, SB)) cst[opnr] -= 1; } - else if ((looking_for & MODE) == REG || - (looking_for & MODE) == LOWREG || - (looking_for & MODE) == IND || - (looking_for & MODE) == PREINC || - (looking_for & MODE) == POSTINC || - (looking_for & MODE) == PREDEC || - (looking_for & MODE) == POSTDEC) + else if ((looking_for & MODE) == REG + || (looking_for & MODE) == LOWREG + || (looking_for & MODE) == IND + || (looking_for & MODE) == PREINC + || (looking_for & MODE) == POSTINC + || (looking_for & MODE) == PREDEC + || (looking_for & MODE) == POSTDEC) { regno[opnr] = thisnib; } - else if (looking_for & CTRL) /* Control Register */ + else if (looking_for & CTRL) /* Control Register. */ { thisnib &= 7; - if (((looking_for & MODE) == CCR && (thisnib != C_CCR)) || - ((looking_for & MODE) == EXR && (thisnib != C_EXR)) || - ((looking_for & MODE) == MACH && (thisnib != C_MACH)) || - ((looking_for & MODE) == MACL && (thisnib != C_MACL)) || - ((looking_for & MODE) == VBR && (thisnib != C_VBR)) || - ((looking_for & MODE) == SBR && (thisnib != C_SBR))) + if (((looking_for & MODE) == CCR && (thisnib != C_CCR)) + || ((looking_for & MODE) == EXR && (thisnib != C_EXR)) + || ((looking_for & MODE) == MACH && (thisnib != C_MACH)) + || ((looking_for & MODE) == MACL && (thisnib != C_MACL)) + || ((looking_for & MODE) == VBR && (thisnib != C_VBR)) + || ((looking_for & MODE) == SBR && (thisnib != C_SBR))) goto fail; - if (((looking_for & MODE) == CCR_EXR && - (thisnib != C_CCR && thisnib != C_EXR)) || - ((looking_for & MODE) == VBR_SBR && - (thisnib != C_VBR && thisnib != C_SBR)) || - ((looking_for & MODE) == MACREG && - (thisnib != C_MACH && thisnib != C_MACL))) + if (((looking_for & MODE) == CCR_EXR + && (thisnib != C_CCR && thisnib != C_EXR)) + || ((looking_for & MODE) == VBR_SBR + && (thisnib != C_VBR && thisnib != C_SBR)) + || ((looking_for & MODE) == MACREG + && (thisnib != C_MACH && thisnib != C_MACL))) goto fail; - if (((looking_for & MODE) == CC_EX_VB_SB && - (thisnib != C_CCR && thisnib != C_EXR && - thisnib != C_VBR && thisnib != C_SBR))) + if (((looking_for & MODE) == CC_EX_VB_SB + && (thisnib != C_CCR && thisnib != C_EXR + && thisnib != C_VBR && thisnib != C_SBR))) goto fail; regno[opnr] = thisnib; @@ -578,8 +513,8 @@ bfd_h8_disassemble (addr, info, mach) cst[opnr] = thisnib; cstlen[opnr] = 4; } - else if ((looking_for & SIZE) == L_16 || - (looking_for & SIZE) == L_16U) + else if ((looking_for & SIZE) == L_16 + || (looking_for & SIZE) == L_16U) { cst[opnr] = (data[len / 2]) * 256 + data[(len + 2) / 2]; cstlen[opnr] = 16; @@ -596,8 +531,8 @@ bfd_h8_disassemble (addr, info, mach) { int i = len / 2; - cst[opnr] = ((data[i] << 24) - | (data[i + 1] << 16) + cst[opnr] = (((unsigned) data[i] << 24) + | (data[i + 1] << 16) | (data[i + 2] << 8) | (data[i + 3])); @@ -607,14 +542,10 @@ bfd_h8_disassemble (addr, info, mach) { int i = len / 2; - cst[opnr] = + cst[opnr] = (data[i] << 16) | (data[i + 1] << 8) | (data[i + 2]); cstlen[opnr] = 24; } - else if (looking_for & IGNORE) - { - ; - } else if (looking_for & DISPREG) { dispregno[opnr] = thisnib & 7; @@ -641,8 +572,8 @@ bfd_h8_disassemble (addr, info, mach) cstlen[opnr] = 8; cst[opnr] = data[len / 2]; } - else if ((looking_for & SIZE) == L_3 || - (looking_for & SIZE) == L_3NZ) + else if ((looking_for & SIZE) == L_3 + || (looking_for & SIZE) == L_3NZ) { cst[opnr] = thisnib & 0x7; if (cst[opnr] == 0 && (looking_for & SIZE) == L_3NZ) @@ -659,14 +590,6 @@ bfd_h8_disassemble (addr, info, mach) } else if (looking_for == (op_type) E) { - int i; - - for (i = 0; i < qi->length; i++) - outfn (stream, "%02x ", data[i]); - - for (; i < 6; i++) - outfn (stream, " "); - outfn (stream, "%s\t", q->name); /* Gross. Disgusting. */ @@ -697,46 +620,55 @@ bfd_h8_disassemble (addr, info, mach) if (regno[0] == 0) outfn (stream, "er%d", regno[1]); else - { - outfn (stream, "(er%d-er%d)", regno[1] - regno[0], - regno[1]); - } + outfn (stream, "er%d-er%d", regno[1] - regno[0], + regno[1]); return qi->length; } - if (strncmp (q->name, "mova", 4) == 0) + if (CONST_STRNEQ (q->name, "mova")) { - op_type *args = q->args.nib; + const op_type *args = q->args.nib; if (args[1] == (op_type) E) { /* Short form. */ - print_one_arg (info, addr, args[0], cst[0], - cstlen[0], dispregno[0], regno[0], + print_one_arg (info, addr, args[0], cst[0], + cstlen[0], dispregno[0], regno[0], pregnames, qi->length); outfn (stream, ",er%d", dispregno[0]); } else { outfn (stream, "@(0x%x:%d,", cst[0], cstlen[0]); - print_one_arg (info, addr, args[1], cst[1], - cstlen[1], dispregno[1], regno[1], + print_one_arg (info, addr, args[1], cst[1], + cstlen[1], dispregno[1], regno[1], pregnames, qi->length); outfn (stream, ".%c),", (args[0] & MODE) == INDEXB ? 'b' : 'w'); - print_one_arg (info, addr, args[2], cst[2], - cstlen[2], dispregno[2], regno[2], + print_one_arg (info, addr, args[2], cst[2], + cstlen[2], dispregno[2], regno[2], pregnames, qi->length); } return qi->length; } /* Fill in the args. */ { - op_type *args = q->args.nib; + const op_type *args = q->args.nib; int hadone = 0; int nargs; - for (nargs = 0; - nargs < 3 && args[nargs] != (op_type) E; + /* Special case handling for the adds and subs instructions + since in H8 mode thay can only take the r0-r7 registers + but in other (higher) modes they can take the er0-er7 + registers as well. */ + if (strcmp (qi->opcode->name, "adds") == 0 + || strcmp (qi->opcode->name, "subs") == 0) + { + outfn (stream, "#%d,%s", cst[0], pregnames[regno[1] & 0x7]); + return qi->length; + } + + for (nargs = 0; + nargs < 3 && args[nargs] != (op_type) E; nargs++) { int x = args[nargs]; @@ -769,32 +701,24 @@ bfd_h8_disassemble (addr, info, mach) } /* Fell off the end. */ - outfn (stream, "%02x %02x .word\tH'%x,H'%x", - data[0], data[1], - data[0], data[1]); + outfn (stream, ".word\tH'%x,H'%x", data[0], data[1]); return 2; } int -print_insn_h8300 (addr, info) - bfd_vma addr; - disassemble_info *info; +print_insn_h8300 (bfd_vma addr, disassemble_info *info) { return bfd_h8_disassemble (addr, info, 0); } int -print_insn_h8300h (addr, info) - bfd_vma addr; - disassemble_info *info; +print_insn_h8300h (bfd_vma addr, disassemble_info *info) { return bfd_h8_disassemble (addr, info, 1); } int -print_insn_h8300s (addr, info) - bfd_vma addr; - disassemble_info *info; +print_insn_h8300s (bfd_vma addr, disassemble_info *info) { return bfd_h8_disassemble (addr, info, 2); }