X-Git-Url: http://git.efficios.com/?a=blobdiff_plain;f=opcodes%2Fh8300-dis.c;h=f56ad86771dd892d6bb66f579b35d48c53579dff;hb=832a580781060f54731fcf654d76ac1332037a47;hp=8b33d86a0a120325ff32a79687e432ed33dd0eb0;hpb=f4321104139af96b8cc3d4946b4e5233d9fa1eab;p=deliverable%2Fbinutils-gdb.git diff --git a/opcodes/h8300-dis.c b/opcodes/h8300-dis.c index 8b33d86a0a..f56ad86771 100644 --- a/opcodes/h8300-dis.c +++ b/opcodes/h8300-dis.c @@ -1,55 +1,45 @@ /* Disassemble h8300 instructions. - Copyright 1993, 1994, 1996, 1998, 2000, 2001, 2002, 2003, 2004 - Free Software Foundation, Inc. + Copyright (C) 1993-2020 Free Software Foundation, Inc. - This program is free software; you can redistribute it and/or modify + This file is part of the GNU opcodes library. + + 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 2 of the License, or - (at your option) any later version. + the Free Software Foundation; either version 3, 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. + 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. */ + 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" struct h8_instruction { - int length; + unsigned int length; const struct h8_opcode *opcode; }; 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 *)); - /* 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; @@ -58,34 +48,15 @@ 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++) ; - - if (i & 1) - { - fprintf (stderr, "Internal error, h8_disassemble_init.\n"); - abort (); - } + OPCODES_ASSERT (!(i & 1)); pi->length = i / 2; pi->opcode = p; @@ -97,13 +68,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) { @@ -114,35 +85,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; @@ -156,12 +129,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; @@ -192,31 +166,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) @@ -262,33 +230,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, @@ -302,67 +263,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 }; @@ -373,8 +321,8 @@ bfd_h8_disassemble (addr, info, mach) const struct h8_instruction *qi; char const **pregnames = mach != 0 ? lregnames : wregnames; int status; - unsigned int l; - unsigned char data[MAX_CODE_NIBBLES]; + unsigned int maxlen; + unsigned char data[MAX_CODE_NIBBLES / 2]; void *stream = info->stream; fprintf_ftype outfn = info->fprintf_func; @@ -391,22 +339,34 @@ bfd_h8_disassemble (addr, info, mach) return -1; } - for (l = 2; status == 0 && l < sizeof (data) / 2; l += 2) - status = info->read_memory_func (addr + l, data + l, 2, info); + for (maxlen = 2; maxlen < sizeof (data); maxlen += 2) + { + status = info->read_memory_func (addr + maxlen, data + maxlen, 2, info); + if (status != 0) + break; + } /* Find the exact opcode/arg combo. */ for (qi = h8_instructions; qi->opcode->name; qi++) { - const struct h8_opcode *q = qi->opcode; - op_type *nib = q->data.nib; - unsigned int len = 0; - - while (1) + const struct h8_opcode *q; + const op_type *nib; + unsigned int len; + op_type looking_for; + + if (qi->length > maxlen) + continue; + + q = qi->opcode; + nib = q->data.nib; + len = 0; + while ((looking_for = *nib) != (op_type) E) { - op_type looking_for = *nib; - int thisnib = data[len / 2]; + int thisnib; int opnr; + OPCODES_ASSERT (len / 2 < maxlen); + thisnib = data[len / 2]; thisnib = (len & 1) ? (thisnib & 0xf) : ((thisnib / 16) & 0xf); opnr = ((looking_for & OP3) == OP3 ? 2 : (looking_for & DST) == DST ? 1 : 0); @@ -501,50 +461,65 @@ 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, + int extra; + switch (looking_for & SIZE) + { + case L_16: + case L_16U: + extra = 1; + break; + case L_32: + extra = 3; + break; + default: + extra = 0; + break; + } + OPCODES_ASSERT (len / 2 + extra < maxlen); + 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; @@ -559,9 +534,10 @@ 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) { + OPCODES_ASSERT (len / 2 + 1 < maxlen); cst[opnr] = (data[len / 2]) * 256 + data[(len + 2) / 2]; cstlen[opnr] = 16; } @@ -575,10 +551,11 @@ bfd_h8_disassemble (addr, info, mach) } else if ((looking_for & SIZE) == L_32) { - int i = len / 2; + unsigned int i = len / 2; - cst[opnr] = ((data[i] << 24) - | (data[i + 1] << 16) + OPCODES_ASSERT (i + 3 < maxlen); + cst[opnr] = (((unsigned) data[i] << 24) + | (data[i + 1] << 16) | (data[i + 2] << 8) | (data[i + 3])); @@ -586,16 +563,13 @@ bfd_h8_disassemble (addr, info, mach) } else if ((looking_for & SIZE) == L_24) { - int i = len / 2; + unsigned int i = len / 2; - cst[opnr] = + OPCODES_ASSERT (i + 2 < maxlen); + 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; @@ -622,8 +596,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) @@ -638,107 +612,6 @@ bfd_h8_disassemble (addr, info, mach) { cst[opnr] = (thisnib == 3); } - else if (looking_for == (op_type) E) - { - outfn (stream, "%s\t", q->name); - - /* Gross. Disgusting. */ - if (strcmp (q->name, "ldm.l") == 0) - { - int count, high; - - count = (data[1] / 16) & 0x3; - high = regno[1]; - - outfn (stream, "@sp+,er%d-er%d", high - count, high); - return qi->length; - } - - if (strcmp (q->name, "stm.l") == 0) - { - int count, low; - - count = (data[1] / 16) & 0x3; - low = regno[0]; - - outfn (stream, "er%d-er%d,@-sp", low, low + count); - return qi->length; - } - if (strcmp (q->name, "rte/l") == 0 - || strcmp (q->name, "rts/l") == 0) - { - if (regno[0] == 0) - outfn (stream, "er%d", regno[1]); - else - { - outfn (stream, "er%d-er%d", regno[1] - regno[0], - regno[1]); - } - return qi->length; - } - if (strncmp (q->name, "mova", 4) == 0) - { - 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], - 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], - 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], - pregnames, qi->length); - } - return qi->length; - } - /* Fill in the args. */ - { - op_type *args = q->args.nib; - int hadone = 0; - int nargs; - - /* 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]; - - if (hadone) - outfn (stream, ","); - - print_one_arg (info, addr, x, - cst[nargs], cstlen[nargs], - dispregno[nargs], regno[nargs], - pregnames, qi->length); - - hadone = 1; - } - } - - return qi->length; - } else /* xgettext:c-format */ outfn (stream, _("Don't understand 0x%x \n"), looking_for); @@ -748,6 +621,102 @@ bfd_h8_disassemble (addr, info, mach) nib++; } + outfn (stream, "%s\t", q->name); + + /* Gross. Disgusting. */ + if (strcmp (q->name, "ldm.l") == 0) + { + int count, high; + + count = (data[1] / 16) & 0x3; + high = regno[1]; + + outfn (stream, "@sp+,er%d-er%d", high - count, high); + return qi->length; + } + + if (strcmp (q->name, "stm.l") == 0) + { + int count, low; + + count = (data[1] / 16) & 0x3; + low = regno[0]; + + outfn (stream, "er%d-er%d,@-sp", low, low + count); + return qi->length; + } + if (strcmp (q->name, "rte/l") == 0 + || strcmp (q->name, "rts/l") == 0) + { + if (regno[0] == 0) + outfn (stream, "er%d", regno[1]); + else + outfn (stream, "er%d-er%d", regno[1] - regno[0], + regno[1]); + return qi->length; + } + if (CONST_STRNEQ (q->name, "mova")) + { + 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], + 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], + 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], + pregnames, qi->length); + } + return qi->length; + } + /* Fill in the args. */ + { + const op_type *args = q->args.nib; + int hadone = 0; + int nargs; + + /* 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]; + + if (hadone) + outfn (stream, ","); + + print_one_arg (info, addr, x, + cst[nargs], cstlen[nargs], + dispregno[nargs], regno[nargs], + pregnames, qi->length); + + hadone = 1; + } + } + return qi->length; + fail: ; } @@ -758,25 +727,19 @@ bfd_h8_disassemble (addr, info, mach) } 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); }