(root)/
binutils-2.41/
opcodes/
h8300-dis.c
       1  /* Disassemble h8300 instructions.
       2     Copyright (C) 1993-2023 Free Software Foundation, Inc.
       3  
       4     This file is part of the GNU opcodes library.
       5  
       6     This library is free software; you can redistribute it and/or modify
       7     it under the terms of the GNU General Public License as published by
       8     the Free Software Foundation; either version 3, or (at your option)
       9     any later version.
      10  
      11     It is distributed in the hope that it will be useful, but WITHOUT
      12     ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
      13     or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
      14     License for more details.
      15  
      16     You should have received a copy of the GNU General Public License
      17     along with this program; if not, write to the Free Software
      18     Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
      19     MA 02110-1301, USA.  */
      20  
      21  #define DEFINE_TABLE
      22  
      23  #include "sysdep.h"
      24  #define h8_opcodes h8ops
      25  #include "opcode/h8300.h"
      26  #include "disassemble.h"
      27  #include "opintl.h"
      28  #include "libiberty.h"
      29  
      30  struct h8_instruction
      31  {
      32    unsigned int length;
      33    const struct h8_opcode *opcode;
      34  };
      35  
      36  struct h8_instruction *h8_instructions;
      37  
      38  /* Run through the opcodes and sort them into order to make them easy
      39     to disassemble.  */
      40  
      41  static void
      42  bfd_h8_disassemble_init (void)
      43  {
      44    unsigned int i;
      45    unsigned int nopcodes;
      46    const struct h8_opcode *p;
      47    struct h8_instruction *pi;
      48  
      49    nopcodes = sizeof (h8_opcodes) / sizeof (struct h8_opcode);
      50  
      51    h8_instructions = xmalloc (nopcodes * sizeof (struct h8_instruction));
      52  
      53    for (p = h8_opcodes, pi = h8_instructions; p->name; p++, pi++)
      54      {
      55        /* Just make sure there are an even number of nibbles in it, and
      56  	 that the count is the same as the length.  */
      57        for (i = 0; p->data.nib[i] != (op_type) E; i++)
      58  	;
      59        OPCODES_ASSERT (!(i & 1));
      60  
      61        pi->length = i / 2;
      62        pi->opcode = p;
      63      }
      64  
      65    /* Add entry for the NULL vector terminator.  */
      66    pi->length = 0;
      67    pi->opcode = p;
      68  }
      69  
      70  static void
      71  extract_immediate (FILE *stream,
      72  		   op_type looking_for,
      73  		   int thisnib,
      74  		   unsigned char *data,
      75  		   int *cst,
      76  		   int *len,
      77  		   const struct h8_opcode *q)
      78  {
      79    switch (looking_for & SIZE)
      80      {
      81      case L_2:
      82        *len = 2;
      83        *cst = thisnib & 3;
      84  
      85        /* DISP2 special treatment.  */
      86        if ((looking_for & MODE) == DISP)
      87  	{
      88  	  if (OP_KIND (q->how) == O_MOVAB
      89  	      || OP_KIND (q->how) == O_MOVAW
      90  	      || OP_KIND (q->how) == O_MOVAL)
      91  	    {
      92  	      /* Handling for mova insn.  */
      93  	      switch (q->args.nib[0] & MODE)
      94  		{
      95  		case INDEXB:
      96  		default:
      97  		  break;
      98  		case INDEXW:
      99  		  *cst *= 2;
     100  		  break;
     101  		case INDEXL:
     102  		  *cst *= 4;
     103  		  break;
     104  		}
     105  	    }
     106  	  else
     107  	    {
     108  	      /* Handling for non-mova insn.  */
     109  	      switch (OP_SIZE (q->how))
     110  		{
     111  		default: break;
     112  		case SW:
     113  		  *cst *= 2;
     114  		  break;
     115  		case SL:
     116  		  *cst *= 4;
     117  		  break;
     118  		}
     119  	    }
     120  	}
     121        break;
     122      case L_8:
     123        *len = 8;
     124        *cst = data[0];
     125        break;
     126      case L_16:
     127      case L_16U:
     128        *len = 16;
     129        *cst = (data[0] << 8) + data [1];
     130  #if 0
     131        if ((looking_for & SIZE) == L_16)
     132  	*cst = (short) *cst;	/* Sign extend.  */
     133  #endif
     134        break;
     135      case L_32:
     136        *len = 32;
     137        *cst = (((unsigned) data[0] << 24) + (data[1] << 16)
     138  	      + (data[2] << 8) + data[3]);
     139        break;
     140      default:
     141        *len = 0;
     142        *cst = 0;
     143        fprintf (stream, "DISP bad size\n");
     144        break;
     145      }
     146  }
     147  
     148  static const char *regnames[] =
     149  {
     150    "r0h", "r1h", "r2h", "r3h", "r4h", "r5h", "r6h", "r7h",
     151    "r0l", "r1l", "r2l", "r3l", "r4l", "r5l", "r6l", "r7l"
     152  };
     153  static const char *wregnames[] =
     154  {
     155    "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
     156    "e0", "e1", "e2", "e3", "e4", "e5", "e6", "e7"
     157  };
     158  static const char *lregnames[] =
     159  {
     160    "er0", "er1", "er2", "er3", "er4", "er5", "er6", "er7",
     161    "er0", "er1", "er2", "er3", "er4", "er5", "er6", "er7"
     162  };
     163  static const char *cregnames[] =
     164  {
     165    "ccr", "exr", "mach", "macl", "", "", "vbr", "sbr"
     166  };
     167  
     168  static void
     169  print_one_arg (disassemble_info *info,
     170  	       bfd_vma addr,
     171  	       op_type x,
     172  	       int cst,
     173  	       int cstlen,
     174  	       int rdisp_n,
     175  	       int rn,
     176  	       const char **pregnames,
     177  	       int len)
     178  {
     179    void * stream = info->stream;
     180    fprintf_ftype outfn = info->fprintf_func;
     181  
     182    if ((x & SIZE) == L_3 || (x & SIZE) == L_3NZ)
     183      outfn (stream, "#0x%x", (unsigned) cst);
     184    else if ((x & MODE) == IMM)
     185      outfn (stream, "#0x%x", (unsigned) cst);
     186    else if ((x & MODE) == DBIT || (x & MODE) == KBIT)
     187      outfn (stream, "#%d", (unsigned) cst);
     188    else if ((x & MODE) == CONST_2)
     189      outfn (stream, "#2");
     190    else if ((x & MODE) == CONST_4)
     191      outfn (stream, "#4");
     192    else if ((x & MODE) == CONST_8)
     193      outfn (stream, "#8");
     194    else if ((x & MODE) == CONST_16)
     195      outfn (stream, "#16");
     196    else if ((x & MODE) == REG)
     197      {
     198        switch (x & SIZE)
     199  	{
     200  	case L_8:
     201  	  outfn (stream, "%s", regnames[rn]);
     202  	  break;
     203  	case L_16:
     204  	case L_16U:
     205  	  outfn (stream, "%s", wregnames[rn]);
     206  	  break;
     207  	case L_P:
     208  	case L_32:
     209  	  outfn (stream, "%s", lregnames[rn]);
     210  	  break;
     211  	}
     212      }
     213    else if ((x & MODE) == LOWREG)
     214      {
     215        switch (x & SIZE)
     216  	{
     217  	case L_8:
     218  	  /* Always take low half of reg.  */
     219  	  outfn (stream, "%s.b", regnames[rn < 8 ? rn + 8 : rn]);
     220  	  break;
     221  	case L_16:
     222  	case L_16U:
     223  	  /* Always take low half of reg.  */
     224  	  outfn (stream, "%s.w", wregnames[rn < 8 ? rn : rn - 8]);
     225  	  break;
     226  	case L_P:
     227  	case L_32:
     228  	  outfn (stream, "%s.l", lregnames[rn]);
     229  	  break;
     230  	}
     231      }
     232    else if ((x & MODE) == POSTINC)
     233      outfn (stream, "@%s+", pregnames[rn]);
     234  
     235    else if ((x & MODE) == POSTDEC)
     236      outfn (stream, "@%s-", pregnames[rn]);
     237  
     238    else if ((x & MODE) == PREINC)
     239      outfn (stream, "@+%s", pregnames[rn]);
     240  
     241    else if ((x & MODE) == PREDEC)
     242      outfn (stream, "@-%s", pregnames[rn]);
     243  
     244    else if ((x & MODE) == IND)
     245      outfn (stream, "@%s", pregnames[rn]);
     246  
     247    else if ((x & MODE) == ABS || (x & ABSJMP))
     248      outfn (stream, "@0x%x:%d", (unsigned) cst, cstlen);
     249  
     250    else if ((x & MODE) == MEMIND)
     251      outfn (stream, "@@%d (0x%x)", cst, cst);
     252  
     253    else if ((x & MODE) == VECIND)
     254      {
     255        /* FIXME Multiplier should be 2 or 4, depending on processor mode,
     256  	 by which is meant "normal" vs. "middle", "advanced", "maximum".  */
     257  
     258        int offset = (cst + 0x80) * 4;
     259        outfn (stream, "@@%d (0x%x)", offset, offset);
     260      }
     261    else if ((x & MODE) == PCREL)
     262      {
     263        if ((x & SIZE) == L_16 ||
     264  	  (x & SIZE) == L_16U)
     265  	{
     266  	  outfn (stream, ".%s%d (0x%lx)",
     267  		   (short) cst > 0 ? "+" : "",
     268  		   (short) cst,
     269  		   (long)(addr + (short) cst + len));
     270  	}
     271        else
     272  	{
     273  	  outfn (stream, ".%s%d (0x%lx)",
     274  		   (char) cst > 0 ? "+" : "",
     275  		   (char) cst,
     276  		   (long)(addr + (char) cst + len));
     277  	}
     278      }
     279    else if ((x & MODE) == DISP)
     280      outfn (stream, "@(0x%x:%d,%s)", cst, cstlen, pregnames[rdisp_n]);
     281  
     282    else if ((x & MODE) == INDEXB)
     283      /* Always take low half of reg.  */
     284      outfn (stream, "@(0x%x:%d,%s.b)", cst, cstlen,
     285  	   regnames[rdisp_n < 8 ? rdisp_n + 8 : rdisp_n]);
     286  
     287    else if ((x & MODE) == INDEXW)
     288      /* Always take low half of reg.  */
     289      outfn (stream, "@(0x%x:%d,%s.w)", cst, cstlen,
     290  	   wregnames[rdisp_n < 8 ? rdisp_n : rdisp_n - 8]);
     291  
     292    else if ((x & MODE) == INDEXL)
     293      outfn (stream, "@(0x%x:%d,%s.l)", cst, cstlen, lregnames[rdisp_n]);
     294  
     295    else if (x & CTRL)
     296      outfn (stream, "%s", cregnames[rn]);
     297  
     298    else if ((x & MODE) == CCR)
     299      outfn (stream, "ccr");
     300  
     301    else if ((x & MODE) == EXR)
     302      outfn (stream, "exr");
     303  
     304    else if ((x & MODE) == MACREG)
     305      outfn (stream, "mac%c", cst ? 'l' : 'h');
     306  
     307    else
     308      /* xgettext:c-format */
     309      outfn (stream, _("Hmmmm 0x%x"), x);
     310  }
     311  
     312  static unsigned int
     313  bfd_h8_disassemble (bfd_vma addr, disassemble_info *info, int mach)
     314  {
     315    /* Find the first entry in the table for this opcode.  */
     316    int regno[3] = { 0, 0, 0 };
     317    int dispregno[3] = { 0, 0, 0 };
     318    int cst[3] = { 0, 0, 0 };
     319    int cstlen[3] = { 0, 0, 0 };
     320    static bool init = 0;
     321    const struct h8_instruction *qi;
     322    char const **pregnames = mach != 0 ? lregnames : wregnames;
     323    int status;
     324    unsigned int maxlen;
     325    unsigned char data[MAX_CODE_NIBBLES / 2];
     326    void *stream = info->stream;
     327    fprintf_ftype outfn = info->fprintf_func;
     328  
     329    if (!init)
     330      {
     331        bfd_h8_disassemble_init ();
     332        init = 1;
     333      }
     334  
     335    status = info->read_memory_func (addr, data, 2, info);
     336    if (status != 0)
     337      {
     338        info->memory_error_func (status, addr, info);
     339        return -1;
     340      }
     341  
     342    for (maxlen = 2; maxlen < sizeof (data); maxlen += 2)
     343      {
     344        status = info->read_memory_func (addr + maxlen, data + maxlen, 2, info);
     345        if (status != 0)
     346  	break;
     347      }
     348  
     349    /* Find the exact opcode/arg combo.  */
     350    for (qi = h8_instructions; qi->opcode->name; qi++)
     351      {
     352        const struct h8_opcode *q;
     353        const op_type *nib;
     354        unsigned int len;
     355        op_type looking_for;
     356  
     357        if (qi->length > maxlen)
     358  	continue;
     359  
     360        q = qi->opcode;
     361        nib = q->data.nib;
     362        len = 0;
     363        while ((looking_for = *nib) != (op_type) E)
     364  	{
     365  	  int thisnib;
     366  	  int opnr;
     367  
     368  	  OPCODES_ASSERT (len / 2 < maxlen);
     369  	  thisnib = data[len / 2];
     370  	  thisnib = (len & 1) ? (thisnib & 0xf) : ((thisnib / 16) & 0xf);
     371  	  opnr = ((looking_for & OP3) == OP3 ? 2
     372  		  : (looking_for & DST) == DST ? 1 : 0);
     373  
     374  	  if (looking_for < 16 && looking_for >= 0)
     375  	    {
     376  	      if (looking_for != thisnib)
     377  		goto fail;
     378  	    }
     379  	  else
     380  	    {
     381  	      if ((int) looking_for & (int) B31)
     382  		{
     383  		  if (!((thisnib & 0x8) != 0))
     384  		    goto fail;
     385  
     386  		  looking_for = (op_type) ((int) looking_for & ~(int) B31);
     387  		  thisnib &= 0x7;
     388  		}
     389  	      else if ((int) looking_for & (int) B30)
     390  		{
     391  		  if (!((thisnib & 0x8) == 0))
     392  		    goto fail;
     393  
     394  		  looking_for = (op_type) ((int) looking_for & ~(int) B30);
     395  		}
     396  
     397  	      if ((int) looking_for & (int) B21)
     398  		{
     399  		  if (!((thisnib & 0x4) != 0))
     400  		    goto fail;
     401  
     402  		  looking_for = (op_type) ((int) looking_for & ~(int) B21);
     403  		  thisnib &= 0xb;
     404  		}
     405  	      else if ((int) looking_for & (int) B20)
     406  		{
     407  		  if (!((thisnib & 0x4) == 0))
     408  		    goto fail;
     409  
     410  		  looking_for = (op_type) ((int) looking_for & ~(int) B20);
     411  		}
     412  	      if ((int) looking_for & (int) B11)
     413  		{
     414  		  if (!((thisnib & 0x2) != 0))
     415  		    goto fail;
     416  
     417  		  looking_for = (op_type) ((int) looking_for & ~(int) B11);
     418  		  thisnib &= 0xd;
     419  		}
     420  	      else if ((int) looking_for & (int) B10)
     421  		{
     422  		  if (!((thisnib & 0x2) == 0))
     423  		    goto fail;
     424  
     425  		  looking_for = (op_type) ((int) looking_for & ~(int) B10);
     426  		}
     427  
     428  	      if ((int) looking_for & (int) B01)
     429  		{
     430  		  if (!((thisnib & 0x1) != 0))
     431  		    goto fail;
     432  
     433  		  looking_for = (op_type) ((int) looking_for & ~(int) B01);
     434  		  thisnib &= 0xe;
     435  		}
     436  	      else if ((int) looking_for & (int) B00)
     437  		{
     438  		  if (!((thisnib & 0x1) == 0))
     439  		    goto fail;
     440  
     441  		  looking_for = (op_type) ((int) looking_for & ~(int) B00);
     442  		}
     443  
     444  	      if (looking_for & IGNORE)
     445  		{
     446  		  /* Hitachi has declared that IGNORE must be zero.  */
     447  		  if (thisnib != 0)
     448  		    goto fail;
     449  		}
     450  	      else if ((looking_for & MODE) == DATA)
     451  		{
     452  		  ;			/* Skip embedded data.  */
     453  		}
     454  	      else if ((looking_for & MODE) == DBIT)
     455  		{
     456  		  /* Exclude adds/subs by looking at bit 0 and 2, and
     457                       make sure the operand size, either w or l,
     458                       matches by looking at bit 1.  */
     459  		  if ((looking_for & 7) != (thisnib & 7))
     460  		    goto fail;
     461  
     462  		  cst[opnr] = (thisnib & 0x8) ? 2 : 1;
     463  		}
     464  	      else if ((looking_for & MODE) == DISP
     465  		       || (looking_for & MODE) == ABS
     466  		       || (looking_for & MODE) == PCREL
     467  		       || (looking_for & MODE) == INDEXB
     468  		       || (looking_for & MODE) == INDEXW
     469  		       || (looking_for & MODE) == INDEXL)
     470  		{
     471  		  int extra;
     472  		  switch (looking_for & SIZE)
     473  		    {
     474  		    case L_16:
     475  		    case L_16U:
     476  		      extra = 1;
     477  		      break;
     478  		    case L_32:
     479  		      extra = 3;
     480  		      break;
     481  		    default:
     482  		      extra = 0;
     483  		      break;
     484  		    }
     485  		  OPCODES_ASSERT (len / 2 + extra < maxlen);
     486  		  extract_immediate (stream, looking_for, thisnib,
     487  				     data + len / 2, cst + opnr,
     488  				     cstlen + opnr, q);
     489  		  /* Even address == bra, odd == bra/s.  */
     490  		  if (q->how == O (O_BRAS, SB))
     491  		    cst[opnr] -= 1;
     492  		}
     493  	      else if ((looking_for & MODE) == REG
     494  		       || (looking_for & MODE) == LOWREG
     495  		       || (looking_for & MODE) == IND
     496  		       || (looking_for & MODE) == PREINC
     497  		       || (looking_for & MODE) == POSTINC
     498  		       || (looking_for & MODE) == PREDEC
     499  		       || (looking_for & MODE) == POSTDEC)
     500  		{
     501  		  regno[opnr] = thisnib;
     502  		}
     503  	      else if (looking_for & CTRL)	/* Control Register.  */
     504  		{
     505  		  thisnib &= 7;
     506  		  if (((looking_for & MODE) == CCR  && (thisnib != C_CCR))
     507  		      || ((looking_for & MODE) == EXR  && (thisnib != C_EXR))
     508  		      || ((looking_for & MODE) == MACH && (thisnib != C_MACH))
     509  		      || ((looking_for & MODE) == MACL && (thisnib != C_MACL))
     510  		      || ((looking_for & MODE) == VBR  && (thisnib != C_VBR))
     511  		      || ((looking_for & MODE) == SBR  && (thisnib != C_SBR)))
     512  		    goto fail;
     513  		  if (((looking_for & MODE) == CCR_EXR
     514  		       && (thisnib != C_CCR && thisnib != C_EXR))
     515  		      || ((looking_for & MODE) == VBR_SBR
     516  			  && (thisnib != C_VBR && thisnib != C_SBR))
     517  		      || ((looking_for & MODE) == MACREG
     518  			  && (thisnib != C_MACH && thisnib != C_MACL)))
     519  		    goto fail;
     520  		  if (((looking_for & MODE) == CC_EX_VB_SB
     521  		       && (thisnib != C_CCR && thisnib != C_EXR
     522  			   && thisnib != C_VBR && thisnib != C_SBR)))
     523  		    goto fail;
     524  
     525  		  regno[opnr] = thisnib;
     526  		}
     527  	      else if ((looking_for & SIZE) == L_5)
     528  		{
     529  		  cst[opnr] = data[len / 2] & 31;
     530  		  cstlen[opnr] = 5;
     531  		}
     532  	      else if ((looking_for & SIZE) == L_4)
     533  		{
     534  		  cst[opnr] = thisnib;
     535  		  cstlen[opnr] = 4;
     536  		}
     537  	      else if ((looking_for & SIZE) == L_16
     538  		       || (looking_for & SIZE) == L_16U)
     539  		{
     540  		  OPCODES_ASSERT (len / 2 + 1 < maxlen);
     541  		  cst[opnr] = (data[len / 2]) * 256 + data[(len + 2) / 2];
     542  		  cstlen[opnr] = 16;
     543  		}
     544  	      else if ((looking_for & MODE) == MEMIND)
     545  		{
     546  		  cst[opnr] = data[1];
     547  		}
     548  	      else if ((looking_for & MODE) == VECIND)
     549  		{
     550  		  cst[opnr] = data[1] & 0x7f;
     551  		}
     552  	      else if ((looking_for & SIZE) == L_32)
     553  		{
     554  		  unsigned int i = len / 2;
     555  
     556  		  OPCODES_ASSERT (i + 3 < maxlen);
     557  		  cst[opnr] = (((unsigned) data[i] << 24)
     558  			       | (data[i + 1] << 16)
     559  			       | (data[i + 2] << 8)
     560  			       | (data[i + 3]));
     561  
     562  		  cstlen[opnr] = 32;
     563  		}
     564  	      else if ((looking_for & SIZE) == L_24)
     565  		{
     566  		  unsigned int i = len / 2;
     567  
     568  		  OPCODES_ASSERT (i + 2 < maxlen);
     569  		  cst[opnr] =
     570  		    (data[i] << 16) | (data[i + 1] << 8) | (data[i + 2]);
     571  		  cstlen[opnr] = 24;
     572  		}
     573  	      else if (looking_for & DISPREG)
     574  		{
     575  		  dispregno[opnr] = thisnib & 7;
     576  		}
     577  	      else if ((looking_for & MODE) == KBIT)
     578  		{
     579  		  switch (thisnib)
     580  		    {
     581  		    case 9:
     582  		      cst[opnr] = 4;
     583  		      break;
     584  		    case 8:
     585  		      cst[opnr] = 2;
     586  		      break;
     587  		    case 0:
     588  		      cst[opnr] = 1;
     589  		      break;
     590  		    default:
     591  		      goto fail;
     592  		    }
     593  		}
     594  	      else if ((looking_for & SIZE) == L_8)
     595  		{
     596  		  cstlen[opnr] = 8;
     597  		  cst[opnr] = data[len / 2];
     598  		}
     599  	      else if ((looking_for & SIZE) == L_3
     600  		       || (looking_for & SIZE) == L_3NZ)
     601  		{
     602  		  cst[opnr] = thisnib & 0x7;
     603  		  if (cst[opnr] == 0 && (looking_for & SIZE) == L_3NZ)
     604  		    goto fail;
     605  		}
     606  	      else if ((looking_for & SIZE) == L_2)
     607  		{
     608  		  cstlen[opnr] = 2;
     609  		  cst[opnr] = thisnib & 0x3;
     610  		}
     611  	      else if ((looking_for & MODE) == MACREG)
     612  		{
     613  		  cst[opnr] = (thisnib == 3);
     614  		}
     615  	      else
     616  		/* xgettext:c-format */
     617  		outfn (stream, _("Don't understand 0x%x \n"), looking_for);
     618  	    }
     619  
     620  	  len++;
     621  	  nib++;
     622  	}
     623  
     624        outfn (stream, "%s\t", q->name);
     625  
     626        /* Gross.  Disgusting.  */
     627        if (strcmp (q->name, "ldm.l") == 0)
     628  	{
     629  	  int count, high;
     630  
     631  	  count = (data[1] / 16) & 0x3;
     632  	  high = regno[1];
     633  
     634  	  outfn (stream, "@sp+,er%d-er%d", high - count, high);
     635  	  return qi->length;
     636  	}
     637  
     638        if (strcmp (q->name, "stm.l") == 0)
     639  	{
     640  	  int count, low;
     641  
     642  	  count = (data[1] / 16) & 0x3;
     643  	  low = regno[0];
     644  
     645  	  outfn (stream, "er%d-er%d,@-sp", low, low + count);
     646  	  return qi->length;
     647  	}
     648        if (strcmp (q->name, "rte/l") == 0
     649  	  || strcmp (q->name, "rts/l") == 0)
     650  	{
     651  	  if (regno[0] == 0)
     652  	    outfn (stream, "er%d", regno[1]);
     653  	  else
     654  	    outfn (stream, "er%d-er%d", regno[1] - regno[0],
     655  		   regno[1]);
     656  	  return qi->length;
     657  	}
     658        if (startswith (q->name, "mova"))
     659  	{
     660  	  const op_type *args = q->args.nib;
     661  
     662  	  if (args[1] == (op_type) E)
     663  	    {
     664  	      /* Short form.  */
     665  	      print_one_arg (info, addr, args[0], cst[0],
     666  			     cstlen[0], dispregno[0], regno[0],
     667  			     pregnames, qi->length);
     668  	      outfn (stream, ",er%d", dispregno[0]);
     669  	    }
     670  	  else
     671  	    {
     672  	      outfn (stream, "@(0x%x:%d,", cst[0], cstlen[0]);
     673  	      print_one_arg (info, addr, args[1], cst[1],
     674  			     cstlen[1], dispregno[1], regno[1],
     675  			     pregnames, qi->length);
     676  	      outfn (stream, ".%c),",
     677  		     (args[0] & MODE) == INDEXB ? 'b' : 'w');
     678  	      print_one_arg (info, addr, args[2], cst[2],
     679  			     cstlen[2], dispregno[2], regno[2],
     680  			     pregnames, qi->length);
     681  	    }
     682  	  return qi->length;
     683  	}
     684        /* Fill in the args.  */
     685        {
     686  	const op_type *args = q->args.nib;
     687  	int hadone = 0;
     688  	int nargs;
     689  
     690  	/* Special case handling for the adds and subs instructions
     691  	   since in H8 mode thay can only take the r0-r7 registers
     692  	   but in other (higher) modes they can take the er0-er7
     693  	   registers as well.  */
     694  	if (strcmp (qi->opcode->name, "adds") == 0
     695  	    || strcmp (qi->opcode->name, "subs") == 0)
     696  	  {
     697  	    outfn (stream, "#%d,%s", cst[0], pregnames[regno[1] & 0x7]);
     698  	    return qi->length;
     699  	  }
     700  
     701  	for (nargs = 0;
     702  	     nargs < 3 && args[nargs] != (op_type) E;
     703  	     nargs++)
     704  	  {
     705  	    int x = args[nargs];
     706  
     707  	    if (hadone)
     708  	      outfn (stream, ",");
     709  
     710  	    print_one_arg (info, addr, x,
     711  			   cst[nargs], cstlen[nargs],
     712  			   dispregno[nargs], regno[nargs],
     713  			   pregnames, qi->length);
     714  
     715  	    hadone = 1;
     716  	  }
     717        }
     718        return qi->length;
     719  
     720      fail:
     721        ;
     722      }
     723  
     724    /* Fell off the end.  */
     725    outfn (stream, ".word\tH'%x,H'%x", data[0], data[1]);
     726    return 2;
     727  }
     728  
     729  int
     730  print_insn_h8300 (bfd_vma addr, disassemble_info *info)
     731  {
     732    return bfd_h8_disassemble (addr, info, 0);
     733  }
     734  
     735  int
     736  print_insn_h8300h (bfd_vma addr, disassemble_info *info)
     737  {
     738    return bfd_h8_disassemble (addr, info, 1);
     739  }
     740  
     741  int
     742  print_insn_h8300s (bfd_vma addr, disassemble_info *info)
     743  {
     744    return bfd_h8_disassemble (addr, info, 2);
     745  }