Home | History | Annotate | Line # | Download | only in opcodes
      1       1.1     skrll /* Print National Semiconductor 32000 instructions.
      2  1.1.1.10  christos    Copyright (C) 1986-2026 Free Software Foundation, Inc.
      3       1.1     skrll 
      4       1.1     skrll    This file is part of the GNU opcodes library.
      5       1.1     skrll 
      6       1.1     skrll    This library is free software; you can redistribute it and/or modify
      7       1.1     skrll    it under the terms of the GNU General Public License as published by
      8       1.1     skrll    the Free Software Foundation; either version 3, or (at your option)
      9       1.1     skrll    any later version.
     10       1.1     skrll 
     11       1.1     skrll    It is distributed in the hope that it will be useful, but WITHOUT
     12       1.1     skrll    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
     13       1.1     skrll    or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
     14       1.1     skrll    License for more details.
     15       1.1     skrll 
     16       1.1     skrll    You should have received a copy of the GNU General Public License
     17       1.1     skrll    along with this program; if not, write to the Free Software
     18       1.1     skrll    Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
     19       1.1     skrll    MA 02110-1301, USA.  */
     20       1.1     skrll 
     21       1.1     skrll #include "sysdep.h"
     22       1.1     skrll #include "bfd.h"
     23   1.1.1.5  christos #include "disassemble.h"
     24       1.1     skrll #if !defined(const) && !defined(__STDC__)
     25       1.1     skrll #define const
     26       1.1     skrll #endif
     27       1.1     skrll #include "opcode/ns32k.h"
     28       1.1     skrll #include "opintl.h"
     29       1.1     skrll 
     30       1.1     skrll static disassemble_info *dis_info;
     31       1.1     skrll 
     32       1.1     skrll /* Hacks to get it to compile <= READ THESE AS FIXES NEEDED.  */
     33       1.1     skrll #define INVALID_FLOAT(val, size) invalid_float ((bfd_byte *) val, size)
     34       1.1     skrll 
     35       1.1     skrll static long
     36       1.1     skrll read_memory_integer (unsigned char * addr, int nr)
     37       1.1     skrll {
     38       1.1     skrll   long val;
     39       1.1     skrll   int i;
     40       1.1     skrll 
     41       1.1     skrll   for (val = 0, i = nr - 1; i >= 0; i--)
     42       1.1     skrll     {
     43       1.1     skrll       val =  (val << 8);
     44       1.1     skrll       val |= (0xff & *(addr + i));
     45       1.1     skrll     }
     46       1.1     skrll   return val;
     47       1.1     skrll }
     48       1.1     skrll 
     49       1.1     skrll /* 32000 instructions are never longer than this.  */
     50       1.1     skrll #define MAXLEN 62
     51       1.1     skrll 
     52       1.1     skrll #include <setjmp.h>
     53       1.1     skrll 
     54       1.1     skrll struct private
     55       1.1     skrll {
     56       1.1     skrll   /* Points to first byte not fetched.  */
     57       1.1     skrll   bfd_byte *max_fetched;
     58       1.1     skrll   bfd_byte the_buffer[MAXLEN];
     59       1.1     skrll   bfd_vma insn_start;
     60   1.1.1.3  christos   OPCODES_SIGJMP_BUF bailout;
     61       1.1     skrll };
     62       1.1     skrll 
     63       1.1     skrll 
     64       1.1     skrll /* Make sure that bytes from INFO->PRIVATE_DATA->BUFFER (inclusive)
     65       1.1     skrll    to ADDR (exclusive) are valid.  Returns 1 for success, longjmps
     66       1.1     skrll    on error.  */
     67       1.1     skrll #define FETCH_DATA(info, addr) \
     68       1.1     skrll   ((addr) <= ((struct private *)(info->private_data))->max_fetched \
     69       1.1     skrll    ? 1 : fetch_data ((info), (addr)))
     70       1.1     skrll 
     71       1.1     skrll static int
     72       1.1     skrll fetch_data (struct disassemble_info *info, bfd_byte *addr)
     73       1.1     skrll {
     74       1.1     skrll   int status;
     75       1.1     skrll   struct private *priv = (struct private *) info->private_data;
     76       1.1     skrll   bfd_vma start = priv->insn_start + (priv->max_fetched - priv->the_buffer);
     77       1.1     skrll 
     78       1.1     skrll   status = (*info->read_memory_func) (start,
     79       1.1     skrll 				      priv->max_fetched,
     80       1.1     skrll 				      addr - priv->max_fetched,
     81       1.1     skrll 				      info);
     82       1.1     skrll   if (status != 0)
     83       1.1     skrll     {
     84       1.1     skrll       (*info->memory_error_func) (status, start, info);
     85   1.1.1.3  christos       OPCODES_SIGLONGJMP (priv->bailout, 1);
     86       1.1     skrll     }
     87       1.1     skrll   else
     88       1.1     skrll     priv->max_fetched = addr;
     89       1.1     skrll   return 1;
     90       1.1     skrll }
     91       1.1     skrll 
     92       1.1     skrll /* Number of elements in the opcode table.  */
     93       1.1     skrll #define NOPCODES (sizeof ns32k_opcodes / sizeof ns32k_opcodes[0])
     94       1.1     skrll 
     95       1.1     skrll #define NEXT_IS_ADDR	'|'
     96       1.1     skrll 
     97       1.1     skrll 
     98       1.1     skrll struct ns32k_option
    100       1.1     skrll {
    101       1.1     skrll   char *pattern;		/* The option itself.  */
    102       1.1     skrll   unsigned long value;		/* Binary value of the option.  */
    103       1.1     skrll   unsigned long match;		/* These bits must match.  */
    104       1.1     skrll };
    105       1.1     skrll 
    106       1.1     skrll 
    107       1.1     skrll static const struct ns32k_option opt_u[]= /* Restore, exit.  */
    109       1.1     skrll {
    110       1.1     skrll   { "r0",	0x80,	0x80	},
    111       1.1     skrll   { "r1",	0x40,	0x40	},
    112       1.1     skrll   { "r2",	0x20,	0x20	},
    113       1.1     skrll   { "r3",	0x10,	0x10	},
    114       1.1     skrll   { "r4",	0x08,	0x08	},
    115       1.1     skrll   { "r5",	0x04,	0x04	},
    116       1.1     skrll   { "r6",	0x02,	0x02	},
    117       1.1     skrll   { "r7",	0x01,	0x01	},
    118       1.1     skrll   {  0 ,	0x00,	0x00	}
    119       1.1     skrll };
    120       1.1     skrll 
    121       1.1     skrll static const struct ns32k_option opt_U[]= /* Save, enter.  */
    122       1.1     skrll {
    123       1.1     skrll   { "r0",	0x01,	0x01	},
    124       1.1     skrll   { "r1",	0x02,	0x02	},
    125       1.1     skrll   { "r2",	0x04,	0x04	},
    126       1.1     skrll   { "r3",	0x08,	0x08	},
    127       1.1     skrll   { "r4",	0x10,	0x10	},
    128       1.1     skrll   { "r5",	0x20,	0x20	},
    129       1.1     skrll   { "r6",	0x40,	0x40	},
    130       1.1     skrll   { "r7",	0x80,	0x80	},
    131       1.1     skrll   {  0 ,	0x00,	0x00	}
    132       1.1     skrll };
    133       1.1     skrll 
    134       1.1     skrll static const struct ns32k_option opt_O[]= /* Setcfg.  */
    135       1.1     skrll {
    136       1.1     skrll   { "c",	0x8,	0x8	},
    137       1.1     skrll   { "m",	0x4,	0x4	},
    138       1.1     skrll   { "f",	0x2,	0x2	},
    139       1.1     skrll   { "i",	0x1,	0x1	},
    140       1.1     skrll   {  0 ,	0x0,	0x0	}
    141       1.1     skrll };
    142       1.1     skrll 
    143       1.1     skrll static const struct ns32k_option opt_C[]= /* Cinv.  */
    144       1.1     skrll {
    145       1.1     skrll   { "a",	0x4,	0x4	},
    146       1.1     skrll   { "i",	0x2,	0x2	},
    147       1.1     skrll   { "d",	0x1,	0x1	},
    148       1.1     skrll   {  0 ,	0x0,	0x0	}
    149       1.1     skrll };
    150       1.1     skrll 
    151       1.1     skrll static const struct ns32k_option opt_S[]= /* String inst.  */
    152       1.1     skrll {
    153       1.1     skrll   { "b",	0x1,	0x1	},
    154       1.1     skrll   { "u",	0x6,	0x6	},
    155       1.1     skrll   { "w",	0x2,	0x2	},
    156       1.1     skrll   {  0 ,	0x0,	0x0	}
    157       1.1     skrll };
    158       1.1     skrll 
    159       1.1     skrll static const struct ns32k_option list_P532[]= /* Lpr spr.  */
    160       1.1     skrll {
    161       1.1     skrll   { "us",	0x0,	0xf	},
    162       1.1     skrll   { "dcr",	0x1,	0xf	},
    163       1.1     skrll   { "bpc",	0x2,	0xf	},
    164       1.1     skrll   { "dsr",	0x3,	0xf	},
    165       1.1     skrll   { "car",	0x4,	0xf	},
    166       1.1     skrll   { "fp",	0x8,	0xf	},
    167       1.1     skrll   { "sp",	0x9,	0xf	},
    168       1.1     skrll   { "sb",	0xa,	0xf	},
    169       1.1     skrll   { "usp",	0xb,	0xf	},
    170       1.1     skrll   { "cfg",	0xc,	0xf	},
    171       1.1     skrll   { "psr",	0xd,	0xf	},
    172       1.1     skrll   { "intbase",	0xe,	0xf	},
    173       1.1     skrll   { "mod",	0xf,	0xf	},
    174       1.1     skrll   {  0 ,	0x00,	0xf	}
    175       1.1     skrll };
    176       1.1     skrll 
    177       1.1     skrll static const struct ns32k_option list_M532[]= /* Lmr smr.  */
    178       1.1     skrll {
    179       1.1     skrll   { "mcr",	0x9,	0xf	},
    180       1.1     skrll   { "msr",	0xa,	0xf	},
    181       1.1     skrll   { "tear",	0xb,	0xf	},
    182       1.1     skrll   { "ptb0",	0xc,	0xf	},
    183       1.1     skrll   { "ptb1",	0xd,	0xf	},
    184       1.1     skrll   { "ivar0",	0xe,	0xf	},
    185       1.1     skrll   { "ivar1",	0xf,	0xf	},
    186       1.1     skrll   {  0 ,	0x0,	0xf	}
    187       1.1     skrll };
    188       1.1     skrll 
    189       1.1     skrll static const struct ns32k_option list_P032[]= /* Lpr spr.  */
    190       1.1     skrll {
    191       1.1     skrll   { "upsr",	0x0,	0xf	},
    192       1.1     skrll   { "fp",	0x8,	0xf	},
    193       1.1     skrll   { "sp",	0x9,	0xf	},
    194       1.1     skrll   { "sb",	0xa,	0xf	},
    195       1.1     skrll   { "psr",	0xb,	0xf	},
    196       1.1     skrll   { "intbase",	0xe,	0xf	},
    197       1.1     skrll   { "mod",	0xf,	0xf	},
    198       1.1     skrll   {  0 ,	0x0,	0xf	}
    199       1.1     skrll };
    200       1.1     skrll 
    201       1.1     skrll static const struct ns32k_option list_M032[]= /* Lmr smr.  */
    202       1.1     skrll {
    203       1.1     skrll   { "bpr0",	0x0,	0xf	},
    204       1.1     skrll   { "bpr1",	0x1,	0xf	},
    205       1.1     skrll   { "pf0",	0x4,	0xf	},
    206       1.1     skrll   { "pf1",	0x5,	0xf	},
    207       1.1     skrll   { "sc",	0x8,	0xf	},
    208       1.1     skrll   { "msr",	0xa,	0xf	},
    209       1.1     skrll   { "bcnt",	0xb,	0xf	},
    210       1.1     skrll   { "ptb0",	0xc,	0xf	},
    211       1.1     skrll   { "ptb1",	0xd,	0xf	},
    212       1.1     skrll   { "eia",	0xf,	0xf	},
    213       1.1     skrll   {  0 ,	0x0,	0xf	}
    214       1.1     skrll };
    215       1.1     skrll 
    216       1.1     skrll 
    217       1.1     skrll /* Figure out which options are present.   */
    218       1.1     skrll 
    219       1.1     skrll static void
    220       1.1     skrll optlist (int options, const struct ns32k_option * optionP, char * result)
    221       1.1     skrll {
    222       1.1     skrll   if (options == 0)
    223       1.1     skrll     {
    224       1.1     skrll       sprintf (result, "[]");
    225       1.1     skrll       return;
    226       1.1     skrll     }
    227       1.1     skrll 
    228       1.1     skrll   sprintf (result, "[");
    229       1.1     skrll 
    230       1.1     skrll   for (; (options != 0) && optionP->pattern; optionP++)
    231       1.1     skrll     {
    232       1.1     skrll       if ((options & optionP->match) == optionP->value)
    233       1.1     skrll 	{
    234       1.1     skrll 	  /* We found a match, update result and options.  */
    235       1.1     skrll 	  strcat (result, optionP->pattern);
    236       1.1     skrll 	  options &= ~optionP->value;
    237       1.1     skrll 	  if (options != 0)	/* More options to come.  */
    238       1.1     skrll 	    strcat (result, ",");
    239       1.1     skrll 	}
    240       1.1     skrll     }
    241       1.1     skrll 
    242       1.1     skrll   if (options != 0)
    243       1.1     skrll     strcat (result, "undefined");
    244       1.1     skrll 
    245       1.1     skrll   strcat (result, "]");
    246       1.1     skrll }
    247       1.1     skrll 
    248       1.1     skrll static void
    249       1.1     skrll list_search (int reg_value, const struct ns32k_option *optionP, char *result)
    250       1.1     skrll {
    251       1.1     skrll   for (; optionP->pattern; optionP++)
    252       1.1     skrll     {
    253       1.1     skrll       if ((reg_value & optionP->match) == optionP->value)
    254       1.1     skrll 	{
    255       1.1     skrll 	  sprintf (result, "%s", optionP->pattern);
    256       1.1     skrll 	  return;
    257       1.1     skrll 	}
    258       1.1     skrll     }
    259       1.1     skrll   sprintf (result, "undefined");
    260       1.1     skrll }
    261       1.1     skrll 
    262       1.1     skrll /* Extract "count" bits starting "offset" bits into buffer.  */
    264       1.1     skrll 
    265   1.1.1.6  christos static int
    266   1.1.1.6  christos bit_extract (bfd_byte *buffer, int offset, int count)
    267       1.1     skrll {
    268   1.1.1.6  christos   unsigned int result;
    269   1.1.1.6  christos   unsigned int bit;
    270       1.1     skrll 
    271       1.1     skrll   if (offset < 0 || count < 0)
    272       1.1     skrll     return 0;
    273       1.1     skrll   buffer += offset >> 3;
    274       1.1     skrll   offset &= 7;
    275       1.1     skrll   bit = 1;
    276       1.1     skrll   result = 0;
    277       1.1     skrll   while (count--)
    278       1.1     skrll     {
    279       1.1     skrll       FETCH_DATA (dis_info, buffer + 1);
    280       1.1     skrll       if ((*buffer & (1 << offset)))
    281       1.1     skrll 	result |= bit;
    282       1.1     skrll       if (++offset == 8)
    283       1.1     skrll 	{
    284       1.1     skrll 	  offset = 0;
    285       1.1     skrll 	  buffer++;
    286       1.1     skrll 	}
    287       1.1     skrll       bit <<= 1;
    288       1.1     skrll     }
    289       1.1     skrll   return result;
    290       1.1     skrll }
    291       1.1     skrll 
    292       1.1     skrll /* Like bit extract but the buffer is valid and doen't need to be fetched.  */
    293       1.1     skrll 
    294   1.1.1.6  christos static int
    295   1.1.1.6  christos bit_extract_simple (bfd_byte *buffer, int offset, int count)
    296       1.1     skrll {
    297   1.1.1.6  christos   unsigned int result;
    298   1.1.1.6  christos   unsigned int bit;
    299       1.1     skrll 
    300       1.1     skrll   if (offset < 0 || count < 0)
    301       1.1     skrll     return 0;
    302       1.1     skrll   buffer += offset >> 3;
    303       1.1     skrll   offset &= 7;
    304       1.1     skrll   bit = 1;
    305       1.1     skrll   result = 0;
    306       1.1     skrll   while (count--)
    307       1.1     skrll     {
    308       1.1     skrll       if ((*buffer & (1 << offset)))
    309       1.1     skrll 	result |= bit;
    310       1.1     skrll       if (++offset == 8)
    311       1.1     skrll 	{
    312       1.1     skrll 	  offset = 0;
    313       1.1     skrll 	  buffer++;
    314       1.1     skrll 	}
    315       1.1     skrll       bit <<= 1;
    316       1.1     skrll     }
    317       1.1     skrll   return result;
    318       1.1     skrll }
    319       1.1     skrll 
    320   1.1.1.6  christos static void
    321   1.1.1.6  christos bit_copy (bfd_byte *buffer, int offset, int count, char *to)
    322       1.1     skrll {
    323       1.1     skrll   if (offset < 0 || count < 0)
    324       1.1     skrll     return;
    325       1.1     skrll   for (; count > 8; count -= 8, to++, offset += 8)
    326       1.1     skrll     *to = bit_extract (buffer, offset, 8);
    327       1.1     skrll   *to = bit_extract (buffer, offset, count);
    328   1.1.1.6  christos }
    329       1.1     skrll 
    330   1.1.1.6  christos static int
    331   1.1.1.6  christos sign_extend (unsigned int value, unsigned int bits)
    332       1.1     skrll {
    333       1.1     skrll   unsigned int sign = 1u << (bits - 1);
    334       1.1     skrll   return ((value & (sign + sign - 1)) ^ sign) - sign;
    335       1.1     skrll }
    336       1.1     skrll 
    337       1.1     skrll static void
    338       1.1     skrll flip_bytes (char *ptr, int count)
    339       1.1     skrll {
    340       1.1     skrll   char tmp;
    341       1.1     skrll 
    342       1.1     skrll   while (count > 0)
    343       1.1     skrll     {
    344       1.1     skrll       tmp = ptr[0];
    345       1.1     skrll       ptr[0] = ptr[count - 1];
    346       1.1     skrll       ptr[count - 1] = tmp;
    347       1.1     skrll       ptr++;
    348       1.1     skrll       count -= 2;
    349       1.1     skrll     }
    350   1.1.1.6  christos }
    351       1.1     skrll 
    352       1.1     skrll /* Given a character C, does it represent a general addressing mode?  */
    354       1.1     skrll #define Is_gen(c) (strchr ("FLBWDAIZf", (c)) != NULL)
    355       1.1     skrll 
    356       1.1     skrll /* Adressing modes.  */
    357       1.1     skrll #define Adrmod_index_byte        0x1c
    358       1.1     skrll #define Adrmod_index_word        0x1d
    359       1.1     skrll #define Adrmod_index_doubleword  0x1e
    360       1.1     skrll #define Adrmod_index_quadword    0x1f
    361       1.1     skrll 
    362       1.1     skrll /* Is MODE an indexed addressing mode?  */
    363       1.1     skrll #define Adrmod_is_index(mode) \
    364       1.1     skrll   (   mode == Adrmod_index_byte \
    365       1.1     skrll    || mode == Adrmod_index_word \
    366       1.1     skrll    || mode == Adrmod_index_doubleword \
    367       1.1     skrll    || mode == Adrmod_index_quadword)
    368       1.1     skrll 
    369       1.1     skrll 
    370       1.1     skrll static int
    372       1.1     skrll get_displacement (bfd_byte *buffer, int *aoffsetp)
    373       1.1     skrll {
    374       1.1     skrll   int Ivalue;
    375       1.1     skrll   short Ivalue2;
    376       1.1     skrll 
    377       1.1     skrll   Ivalue = bit_extract (buffer, *aoffsetp, 8);
    378       1.1     skrll   switch (Ivalue & 0xc0)
    379       1.1     skrll     {
    380       1.1     skrll     case 0x00:
    381       1.1     skrll     case 0x40:
    382       1.1     skrll       Ivalue = sign_extend (Ivalue, 7);
    383       1.1     skrll       *aoffsetp += 8;
    384       1.1     skrll       break;
    385       1.1     skrll     case 0x80:
    386       1.1     skrll       Ivalue2 = bit_extract (buffer, *aoffsetp, 16);
    387       1.1     skrll       flip_bytes ((char *) & Ivalue2, 2);
    388       1.1     skrll       Ivalue = sign_extend (Ivalue2, 14);
    389       1.1     skrll       *aoffsetp += 16;
    390       1.1     skrll       break;
    391       1.1     skrll     case 0xc0:
    392       1.1     skrll       Ivalue = bit_extract (buffer, *aoffsetp, 32);
    393       1.1     skrll       flip_bytes ((char *) & Ivalue, 4);
    394       1.1     skrll       Ivalue = sign_extend (Ivalue, 30);
    395       1.1     skrll       *aoffsetp += 32;
    396       1.1     skrll       break;
    397       1.1     skrll     }
    398       1.1     skrll   return Ivalue;
    399       1.1     skrll }
    400       1.1     skrll 
    401       1.1     skrll #if 1 /* A version that should work on ns32k f's&d's on any machine.  */
    402       1.1     skrll static int
    403       1.1     skrll invalid_float (bfd_byte *p, int len)
    404       1.1     skrll {
    405       1.1     skrll   int val;
    406       1.1     skrll 
    407       1.1     skrll   if (len == 4)
    408       1.1     skrll     val = (bit_extract_simple (p, 23, 8)/*exponent*/ == 0xff
    409       1.1     skrll 	   || (bit_extract_simple (p, 23, 8)/*exponent*/ == 0
    410       1.1     skrll 	       && bit_extract_simple (p, 0, 23)/*mantisa*/ != 0));
    411       1.1     skrll   else if (len == 8)
    412       1.1     skrll     val = (bit_extract_simple (p, 52, 11)/*exponent*/ == 0x7ff
    413       1.1     skrll 	   || (bit_extract_simple (p, 52, 11)/*exponent*/ == 0
    414       1.1     skrll 	       && (bit_extract_simple (p, 0, 32)/*low mantisa*/ != 0
    415       1.1     skrll 		   || bit_extract_simple (p, 32, 20)/*high mantisa*/ != 0)));
    416       1.1     skrll   else
    417       1.1     skrll     val = 1;
    418   1.1.1.3  christos   return (val);
    419       1.1     skrll }
    420       1.1     skrll #else
    421       1.1     skrll /* Assumes the bytes have been swapped to local order.  */
    422       1.1     skrll typedef union
    423       1.1     skrll {
    424       1.1     skrll   double d;
    425       1.1     skrll   float f;
    426       1.1     skrll   struct { unsigned m:23, e:8, :1;} sf;
    427       1.1     skrll   struct { unsigned lm; unsigned m:20, e:11, :1;} sd;
    428       1.1     skrll } float_type_u;
    429       1.1     skrll 
    430       1.1     skrll static int
    431       1.1     skrll invalid_float (float_type_u *p, int len)
    432       1.1     skrll {
    433       1.1     skrll   int val;
    434       1.1     skrll 
    435       1.1     skrll   if (len == sizeof (float))
    436       1.1     skrll     val = (p->sf.e == 0xff
    437       1.1     skrll 	   || (p->sf.e == 0 && p->sf.m != 0));
    438       1.1     skrll   else if (len == sizeof (double))
    439       1.1     skrll     val = (p->sd.e == 0x7ff
    440       1.1     skrll 	   || (p->sd.e == 0 && (p->sd.m != 0 || p->sd.lm != 0)));
    441       1.1     skrll   else
    442       1.1     skrll     val = 1;
    443       1.1     skrll   return val;
    444       1.1     skrll }
    445       1.1     skrll #endif
    446       1.1     skrll 
    447       1.1     skrll /* Print an instruction operand of category given by d.  IOFFSET is
    448       1.1     skrll    the bit position below which small (<1 byte) parts of the operand can
    449   1.1.1.7  christos    be found (usually in the basic instruction, but for indexed
    450       1.1     skrll    addressing it can be in the index byte).  AOFFSETP is a pointer to the
    451       1.1     skrll    bit position of the addressing extension.  BUFFER contains the
    452       1.1     skrll    instruction.  ADDR is where BUFFER was read from.  Put the disassembled
    453       1.1     skrll    version of the operand in RESULT.  INDEX_OFFSET is the bit position
    454       1.1     skrll    of the index byte (it contains -1 if this operand is not a
    455       1.1     skrll    general operand using scaled indexed addressing mode).  */
    456       1.1     skrll 
    457       1.1     skrll static int
    458       1.1     skrll print_insn_arg (int d,
    459       1.1     skrll 		int ioffset,
    460       1.1     skrll 		int *aoffsetp,
    461       1.1     skrll 		bfd_byte *buffer,
    462       1.1     skrll 		bfd_vma addr,
    463       1.1     skrll 		char *result,
    464       1.1     skrll 		int index_offset)
    465       1.1     skrll {
    466       1.1     skrll   union
    467       1.1     skrll   {
    468       1.1     skrll     float f;
    469       1.1     skrll     double d;
    470       1.1     skrll     int i[2];
    471       1.1     skrll   } value;
    472       1.1     skrll   int Ivalue;
    473       1.1     skrll   int addr_mode;
    474       1.1     skrll   int disp1, disp2;
    475       1.1     skrll   int size;
    476       1.1     skrll 
    477   1.1.1.5  christos   switch (d)
    478       1.1     skrll     {
    479       1.1     skrll     case 'f':
    480       1.1     skrll       /* A "gen" operand but 5 bits from the end of instruction.  */
    481       1.1     skrll       ioffset -= 5;
    482       1.1     skrll       /* Fall through.  */
    483       1.1     skrll     case 'Z':
    484       1.1     skrll     case 'F':
    485       1.1     skrll     case 'L':
    486       1.1     skrll     case 'I':
    487       1.1     skrll     case 'B':
    488       1.1     skrll     case 'W':
    489       1.1     skrll     case 'D':
    490       1.1     skrll     case 'A':
    491       1.1     skrll       addr_mode = bit_extract (buffer, ioffset - 5, 5);
    492       1.1     skrll       ioffset -= 5;
    493       1.1     skrll       switch (addr_mode)
    494       1.1     skrll 	{
    495       1.1     skrll 	case 0x0: case 0x1: case 0x2: case 0x3:
    496       1.1     skrll 	case 0x4: case 0x5: case 0x6: case 0x7:
    497       1.1     skrll 	  /* Register mode R0 -- R7.  */
    498       1.1     skrll 	  switch (d)
    499       1.1     skrll 	    {
    500       1.1     skrll 	    case 'F':
    501       1.1     skrll 	    case 'L':
    502       1.1     skrll 	    case 'Z':
    503       1.1     skrll 	      sprintf (result, "f%d", addr_mode);
    504       1.1     skrll 	      break;
    505       1.1     skrll 	    default:
    506       1.1     skrll 	      sprintf (result, "r%d", addr_mode);
    507       1.1     skrll 	    }
    508       1.1     skrll 	  break;
    509       1.1     skrll 	case 0x8: case 0x9: case 0xa: case 0xb:
    510       1.1     skrll 	case 0xc: case 0xd: case 0xe: case 0xf:
    511       1.1     skrll 	  /* Register relative disp(R0 -- R7).  */
    512       1.1     skrll 	  disp1 = get_displacement (buffer, aoffsetp);
    513       1.1     skrll 	  sprintf (result, "%d(r%d)", disp1, addr_mode & 7);
    514       1.1     skrll 	  break;
    515       1.1     skrll 	case 0x10:
    516       1.1     skrll 	case 0x11:
    517       1.1     skrll 	case 0x12:
    518       1.1     skrll 	  /* Memory relative disp2(disp1(FP, SP, SB)).  */
    519       1.1     skrll 	  disp1 = get_displacement (buffer, aoffsetp);
    520       1.1     skrll 	  disp2 = get_displacement (buffer, aoffsetp);
    521       1.1     skrll 	  sprintf (result, "%d(%d(%s))", disp2, disp1,
    522       1.1     skrll 		   addr_mode == 0x10 ? "fp" : addr_mode == 0x11 ? "sp" : "sb");
    523       1.1     skrll 	  break;
    524       1.1     skrll 	case 0x13:
    525       1.1     skrll 	  /* Reserved.  */
    526       1.1     skrll 	  sprintf (result, "reserved");
    527   1.1.1.7  christos 	  break;
    528       1.1     skrll 	case 0x14:
    529       1.1     skrll 	  /* Immediate.  */
    530       1.1     skrll 	  switch (d)
    531       1.1     skrll 	    {
    532       1.1     skrll 	    default:
    533       1.1     skrll 	      /* I and Z are output operands and can`t be immediate
    534       1.1     skrll 	         A is an address and we can`t have the address of
    535       1.1     skrll 	         an immediate either. We don't know how much to increase
    536       1.1     skrll 	         aoffsetp by since whatever generated this is broken
    537       1.1     skrll 	         anyway!  */
    538       1.1     skrll 	      sprintf (result, _("$<undefined>"));
    539       1.1     skrll 	      break;
    540       1.1     skrll 	    case 'B':
    541       1.1     skrll 	      Ivalue = bit_extract (buffer, *aoffsetp, 8);
    542       1.1     skrll 	      Ivalue = sign_extend (Ivalue, 8);
    543       1.1     skrll 	      *aoffsetp += 8;
    544       1.1     skrll 	      sprintf (result, "$%d", Ivalue);
    545       1.1     skrll 	      break;
    546       1.1     skrll 	    case 'W':
    547       1.1     skrll 	      Ivalue = bit_extract (buffer, *aoffsetp, 16);
    548       1.1     skrll 	      flip_bytes ((char *) & Ivalue, 2);
    549       1.1     skrll 	      *aoffsetp += 16;
    550       1.1     skrll 	      Ivalue = sign_extend (Ivalue, 16);
    551       1.1     skrll 	      sprintf (result, "$%d", Ivalue);
    552       1.1     skrll 	      break;
    553       1.1     skrll 	    case 'D':
    554       1.1     skrll 	      Ivalue = bit_extract (buffer, *aoffsetp, 32);
    555       1.1     skrll 	      flip_bytes ((char *) & Ivalue, 4);
    556       1.1     skrll 	      *aoffsetp += 32;
    557       1.1     skrll 	      sprintf (result, "$%d", Ivalue);
    558       1.1     skrll 	      break;
    559       1.1     skrll 	    case 'F':
    560       1.1     skrll 	      bit_copy (buffer, *aoffsetp, 32, (char *) &value.f);
    561       1.1     skrll 	      flip_bytes ((char *) &value.f, 4);
    562       1.1     skrll 	      *aoffsetp += 32;
    563       1.1     skrll 	      if (INVALID_FLOAT (&value.f, 4))
    564       1.1     skrll 		sprintf (result, "<<invalid float 0x%.8x>>", value.i[0]);
    565       1.1     skrll 	      else /* Assume host has ieee float.  */
    566       1.1     skrll 		sprintf (result, "$%g", value.f);
    567       1.1     skrll 	      break;
    568       1.1     skrll 	    case 'L':
    569       1.1     skrll 	      bit_copy (buffer, *aoffsetp, 64, (char *) &value.d);
    570       1.1     skrll 	      flip_bytes ((char *) &value.d, 8);
    571       1.1     skrll 	      *aoffsetp += 64;
    572       1.1     skrll 	      if (INVALID_FLOAT (&value.d, 8))
    573       1.1     skrll 		sprintf (result, "<<invalid double 0x%.8x%.8x>>",
    574       1.1     skrll 			 value.i[1], value.i[0]);
    575       1.1     skrll 	      else /* Assume host has ieee float.  */
    576       1.1     skrll 		sprintf (result, "$%g", value.d);
    577       1.1     skrll 	      break;
    578       1.1     skrll 	    }
    579       1.1     skrll 	  break;
    580       1.1     skrll 	case 0x15:
    581       1.1     skrll 	  /* Absolute @disp.  */
    582       1.1     skrll 	  disp1 = get_displacement (buffer, aoffsetp);
    583       1.1     skrll 	  sprintf (result, "@|%d|", disp1);
    584       1.1     skrll 	  break;
    585       1.1     skrll 	case 0x16:
    586       1.1     skrll 	  /* External EXT(disp1) + disp2 (Mod table stuff).  */
    587       1.1     skrll 	  disp1 = get_displacement (buffer, aoffsetp);
    588       1.1     skrll 	  disp2 = get_displacement (buffer, aoffsetp);
    589       1.1     skrll 	  sprintf (result, "EXT(%d) + %d", disp1, disp2);
    590       1.1     skrll 	  break;
    591       1.1     skrll 	case 0x17:
    592       1.1     skrll 	  /* Top of stack tos.  */
    593       1.1     skrll 	  sprintf (result, "tos");
    594       1.1     skrll 	  break;
    595       1.1     skrll 	case 0x18:
    596       1.1     skrll 	  /* Memory space disp(FP).  */
    597       1.1     skrll 	  disp1 = get_displacement (buffer, aoffsetp);
    598       1.1     skrll 	  sprintf (result, "%d(fp)", disp1);
    599       1.1     skrll 	  break;
    600       1.1     skrll 	case 0x19:
    601       1.1     skrll 	  /* Memory space disp(SP).  */
    602       1.1     skrll 	  disp1 = get_displacement (buffer, aoffsetp);
    603       1.1     skrll 	  sprintf (result, "%d(sp)", disp1);
    604       1.1     skrll 	  break;
    605       1.1     skrll 	case 0x1a:
    606       1.1     skrll 	  /* Memory space disp(SB).  */
    607       1.1     skrll 	  disp1 = get_displacement (buffer, aoffsetp);
    608       1.1     skrll 	  sprintf (result, "%d(sb)", disp1);
    609   1.1.1.8  christos 	  break;
    610       1.1     skrll 	case 0x1b:
    611       1.1     skrll 	  /* Memory space disp(PC).  */
    612       1.1     skrll 	  disp1 = get_displacement (buffer, aoffsetp);
    613       1.1     skrll 	  *result++ = NEXT_IS_ADDR;
    614       1.1     skrll 	  sprintf (result, "%" PRIx64, (uint64_t) (addr + disp1));
    615       1.1     skrll 	  result += strlen (result);
    616       1.1     skrll 	  *result++ = NEXT_IS_ADDR;
    617       1.1     skrll 	  *result = '\0';
    618       1.1     skrll 	  break;
    619   1.1.1.2  christos 	case 0x1c:
    620       1.1     skrll 	case 0x1d:
    621       1.1     skrll 	case 0x1e:
    622   1.1.1.3  christos 	case 0x1f:
    623   1.1.1.2  christos 	  {
    624   1.1.1.2  christos 	    int bit_index;
    625   1.1.1.2  christos 	    static const char *ind = "bwdq";
    626   1.1.1.2  christos 	    char *off;
    627       1.1     skrll 
    628   1.1.1.2  christos 	    /* Scaled index basemode[R0 -- R7:B,W,D,Q].  */
    629       1.1     skrll 	    bit_index = bit_extract (buffer, index_offset - 8, 3);
    630       1.1     skrll 	    print_insn_arg (d, index_offset, aoffsetp, buffer, addr,
    631       1.1     skrll 			    result, 0);
    632       1.1     skrll 	    off = result + strlen (result);
    633       1.1     skrll 	    sprintf (off, "[r%d:%c]", bit_index, ind[addr_mode & 3]);
    634       1.1     skrll 	  }
    635       1.1     skrll 	  break;
    636       1.1     skrll 	}
    637       1.1     skrll       break;
    638       1.1     skrll     case 'H':
    639       1.1     skrll     case 'q':
    640       1.1     skrll       Ivalue = bit_extract (buffer, ioffset-4, 4);
    641       1.1     skrll       Ivalue = sign_extend (Ivalue, 4);
    642       1.1     skrll       sprintf (result, "%d", Ivalue);
    643       1.1     skrll       ioffset -= 4;
    644       1.1     skrll       break;
    645       1.1     skrll     case 'r':
    646       1.1     skrll       Ivalue = bit_extract (buffer, ioffset-3, 3);
    647       1.1     skrll       sprintf (result, "r%d", Ivalue&7);
    648       1.1     skrll       ioffset -= 3;
    649       1.1     skrll       break;
    650       1.1     skrll     case 'd':
    651       1.1     skrll       sprintf (result, "%d", get_displacement (buffer, aoffsetp));
    652       1.1     skrll       break;
    653       1.1     skrll     case 'b':
    654       1.1     skrll       Ivalue = get_displacement (buffer, aoffsetp);
    655       1.1     skrll       /* Warning!!  HACK ALERT!
    656       1.1     skrll          Operand type 'b' is only used by the cmp{b,w,d} and
    657       1.1     skrll          movm{b,w,d} instructions; we need to know whether
    658       1.1     skrll          it's a `b' or `w' or `d' instruction; and for both
    659       1.1     skrll          cmpm and movm it's stored at the same place so we
    660       1.1     skrll          just grab two bits of the opcode and look at it...  */
    661       1.1     skrll       size = bit_extract(buffer, ioffset-6, 2);
    662       1.1     skrll       if (size == 0)		/* 00 => b.  */
    663       1.1     skrll 	size = 1;
    664       1.1     skrll       else if (size == 1)	/* 01 => w.  */
    665       1.1     skrll 	size = 2;
    666       1.1     skrll       else
    667       1.1     skrll 	size = 4;		/* 11 => d.  */
    668   1.1.1.8  christos 
    669   1.1.1.8  christos       sprintf (result, "%d", (Ivalue / size) + 1);
    670       1.1     skrll       break;
    671       1.1     skrll     case 'p':
    672       1.1     skrll       *result++ = NEXT_IS_ADDR;
    673       1.1     skrll       sprintf (result, "%" PRIx64,
    674       1.1     skrll 	       (uint64_t) (addr + get_displacement (buffer, aoffsetp)));
    675       1.1     skrll       result += strlen (result);
    676       1.1     skrll       *result++ = NEXT_IS_ADDR;
    677       1.1     skrll       *result = '\0';
    678       1.1     skrll       break;
    679       1.1     skrll     case 'i':
    680       1.1     skrll       Ivalue = bit_extract (buffer, *aoffsetp, 8);
    681       1.1     skrll       *aoffsetp += 8;
    682       1.1     skrll       sprintf (result, "0x%x", Ivalue);
    683       1.1     skrll       break;
    684       1.1     skrll     case 'u':
    685       1.1     skrll       Ivalue = bit_extract (buffer, *aoffsetp, 8);
    686       1.1     skrll       optlist (Ivalue, opt_u, result);
    687       1.1     skrll       *aoffsetp += 8;
    688       1.1     skrll       break;
    689       1.1     skrll     case 'U':
    690       1.1     skrll       Ivalue = bit_extract (buffer, *aoffsetp, 8);
    691       1.1     skrll       optlist (Ivalue, opt_U, result);
    692       1.1     skrll       *aoffsetp += 8;
    693       1.1     skrll       break;
    694       1.1     skrll     case 'O':
    695       1.1     skrll       Ivalue = bit_extract (buffer, ioffset - 9, 9);
    696       1.1     skrll       optlist (Ivalue, opt_O, result);
    697       1.1     skrll       ioffset -= 9;
    698       1.1     skrll       break;
    699       1.1     skrll     case 'C':
    700       1.1     skrll       Ivalue = bit_extract (buffer, ioffset - 4, 4);
    701       1.1     skrll       optlist (Ivalue, opt_C, result);
    702       1.1     skrll       ioffset -= 4;
    703       1.1     skrll       break;
    704       1.1     skrll     case 'S':
    705       1.1     skrll       Ivalue = bit_extract (buffer, ioffset - 8, 8);
    706       1.1     skrll       optlist (Ivalue, opt_S, result);
    707       1.1     skrll       ioffset -= 8;
    708       1.1     skrll       break;
    709       1.1     skrll     case 'M':
    710       1.1     skrll       Ivalue = bit_extract (buffer, ioffset - 4, 4);
    711       1.1     skrll       list_search (Ivalue, 0 ? list_M032 : list_M532, result);
    712       1.1     skrll       ioffset -= 4;
    713       1.1     skrll       break;
    714       1.1     skrll     case 'P':
    715       1.1     skrll       Ivalue = bit_extract (buffer, ioffset - 4, 4);
    716       1.1     skrll       list_search (Ivalue, 0 ? list_P032 : list_P532, result);
    717       1.1     skrll       ioffset -= 4;
    718       1.1     skrll       break;
    719       1.1     skrll     case 'g':
    720       1.1     skrll       Ivalue = bit_extract (buffer, *aoffsetp, 3);
    721       1.1     skrll       sprintf (result, "%d", Ivalue);
    722       1.1     skrll       *aoffsetp += 3;
    723       1.1     skrll       break;
    724       1.1     skrll     case 'G':
    725       1.1     skrll       Ivalue = bit_extract(buffer, *aoffsetp, 5);
    726       1.1     skrll       sprintf (result, "%d", Ivalue + 1);
    727       1.1     skrll       *aoffsetp += 5;
    728       1.1     skrll       break;
    729       1.1     skrll     }
    730       1.1     skrll   return ioffset;
    731       1.1     skrll }
    732       1.1     skrll 
    733       1.1     skrll 
    734       1.1     skrll /* Print the 32000 instruction at address MEMADDR in debugged memory,
    736       1.1     skrll    on STREAM.  Returns length of the instruction, in bytes.  */
    737       1.1     skrll 
    738       1.1     skrll int
    739       1.1     skrll print_insn_ns32k (bfd_vma memaddr, disassemble_info *info)
    740       1.1     skrll {
    741       1.1     skrll   unsigned int i;
    742       1.1     skrll   const char *d;
    743       1.1     skrll   unsigned short first_word;
    744       1.1     skrll   int ioffset;		/* Bits into instruction.  */
    745       1.1     skrll   int aoffset;		/* Bits into arguments.  */
    746       1.1     skrll   char arg_bufs[MAX_ARGS+1][ARG_LEN];
    747       1.1     skrll   int argnum;
    748       1.1     skrll   int maxarg;
    749       1.1     skrll   struct private priv;
    750   1.1.1.3  christos   bfd_byte *buffer = priv.the_buffer;
    751       1.1     skrll   dis_info = info;
    752       1.1     skrll 
    753       1.1     skrll   info->private_data = & priv;
    754       1.1     skrll   priv.max_fetched = priv.the_buffer;
    755       1.1     skrll   priv.insn_start = memaddr;
    756       1.1     skrll   if (OPCODES_SIGSETJMP (priv.bailout) != 0)
    757       1.1     skrll     /* Error return.  */
    758       1.1     skrll     return -1;
    759       1.1     skrll 
    760       1.1     skrll   /* Look for 8bit opcodes first. Other wise, fetching two bytes could take
    761       1.1     skrll      us over the end of accessible data unnecessarilly.  */
    762       1.1     skrll   FETCH_DATA (info, buffer + 1);
    763       1.1     skrll   for (i = 0; i < NOPCODES; i++)
    764       1.1     skrll     if (ns32k_opcodes[i].opcode_id_size <= 8
    765       1.1     skrll 	&& ((buffer[0]
    766       1.1     skrll 	     & (((unsigned long) 1 << ns32k_opcodes[i].opcode_id_size) - 1))
    767       1.1     skrll 	    == ns32k_opcodes[i].opcode_seed))
    768       1.1     skrll       break;
    769       1.1     skrll   if (i == NOPCODES)
    770       1.1     skrll     {
    771       1.1     skrll       /* Maybe it is 9 to 16 bits big.  */
    772       1.1     skrll       FETCH_DATA (info, buffer + 2);
    773       1.1     skrll       first_word = read_memory_integer(buffer, 2);
    774       1.1     skrll 
    775       1.1     skrll       for (i = 0; i < NOPCODES; i++)
    776       1.1     skrll 	if ((first_word
    777       1.1     skrll 	     & (((unsigned long) 1 << ns32k_opcodes[i].opcode_id_size) - 1))
    778       1.1     skrll 	    == ns32k_opcodes[i].opcode_seed)
    779       1.1     skrll 	  break;
    780       1.1     skrll 
    781       1.1     skrll       /* Handle undefined instructions.  */
    782       1.1     skrll       if (i == NOPCODES)
    783       1.1     skrll 	{
    784       1.1     skrll 	  (*dis_info->fprintf_func)(dis_info->stream, "0%o", buffer[0]);
    785       1.1     skrll 	  return 1;
    786       1.1     skrll 	}
    787       1.1     skrll     }
    788       1.1     skrll 
    789       1.1     skrll   (*dis_info->fprintf_func)(dis_info->stream, "%s", ns32k_opcodes[i].name);
    790       1.1     skrll 
    791       1.1     skrll   ioffset = ns32k_opcodes[i].opcode_size;
    792   1.1.1.7  christos   aoffset = ns32k_opcodes[i].opcode_size;
    793   1.1.1.7  christos   d = ns32k_opcodes[i].operands;
    794       1.1     skrll 
    795       1.1     skrll   if (*d)
    796       1.1     skrll     {
    797   1.1.1.3  christos       /* Offset in bits of the first thing beyond each index byte.
    798       1.1     skrll 	 Element 0 is for operand A and element 1 is for operand B.  */
    799       1.1     skrll       int index_offset[2];
    800       1.1     skrll 
    801       1.1     skrll       /* 0 for operand A, 1 for operand B, greater for other args.  */
    802       1.1     skrll       int whicharg = 0;
    803       1.1     skrll 
    804       1.1     skrll       (*dis_info->fprintf_func)(dis_info->stream, "\t");
    805       1.1     skrll 
    806   1.1.1.7  christos       maxarg = 0;
    807   1.1.1.7  christos 
    808   1.1.1.6  christos       /* First we have to find and keep track of the index bytes,
    809       1.1     skrll 	 if we are using scaled indexed addressing mode, since the index
    810   1.1.1.6  christos 	 bytes occur right after the basic instruction, not as part
    811   1.1.1.6  christos 	 of the addressing extension.  */
    812       1.1     skrll       index_offset[0] = -1;
    813       1.1     skrll       index_offset[1] = -1;
    814       1.1     skrll       if (Is_gen (d[1]))
    815       1.1     skrll 	{
    816       1.1     skrll 	  int bitoff = d[1] == 'f' ? 10 : 5;
    817       1.1     skrll 	  int addr_mode = bit_extract (buffer, ioffset - bitoff, 5);
    818       1.1     skrll 
    819       1.1     skrll 	  if (Adrmod_is_index (addr_mode))
    820   1.1.1.6  christos 	    {
    821       1.1     skrll 	      aoffset += 8;
    822       1.1     skrll 	      index_offset[0] = aoffset;
    823       1.1     skrll 	    }
    824       1.1     skrll 	}
    825       1.1     skrll 
    826       1.1     skrll       if (d[2] && Is_gen (d[3]))
    827       1.1     skrll 	{
    828       1.1     skrll 	  int addr_mode = bit_extract (buffer, ioffset - 10, 5);
    829       1.1     skrll 
    830       1.1     skrll 	  if (Adrmod_is_index (addr_mode))
    831       1.1     skrll 	    {
    832       1.1     skrll 	      aoffset += 8;
    833       1.1     skrll 	      index_offset[1] = aoffset;
    834   1.1.1.7  christos 	    }
    835   1.1.1.7  christos 	}
    836       1.1     skrll 
    837   1.1.1.7  christos       while (*d)
    838       1.1     skrll 	{
    839       1.1     skrll 	  argnum = *d - '1';
    840       1.1     skrll 	  if (argnum >= MAX_ARGS)
    841   1.1.1.7  christos 	    abort ();
    842       1.1     skrll 	  d++;
    843   1.1.1.7  christos 	  if (argnum > maxarg)
    844       1.1     skrll 	    maxarg = argnum;
    845   1.1.1.6  christos 	  ioffset = print_insn_arg (*d, ioffset, &aoffset, buffer,
    846       1.1     skrll 				    memaddr, arg_bufs[argnum],
    847       1.1     skrll 				    whicharg > 1 ? -1 : index_offset[whicharg]);
    848       1.1     skrll 	  d++;
    849       1.1     skrll 	  whicharg++;
    850       1.1     skrll 	}
    851       1.1     skrll 
    852       1.1     skrll       for (argnum = 0; argnum <= maxarg; argnum++)
    853       1.1     skrll 	{
    854       1.1     skrll 	  bfd_vma addr;
    855       1.1     skrll 	  char *ch;
    856       1.1     skrll 
    857       1.1     skrll 	  for (ch = arg_bufs[argnum]; *ch;)
    858       1.1     skrll 	    {
    859       1.1     skrll 	      if (*ch == NEXT_IS_ADDR)
    860       1.1     skrll 		{
    861       1.1     skrll 		  ++ch;
    862       1.1     skrll 		  addr = bfd_scan_vma (ch, NULL, 16);
    863       1.1     skrll 		  (*dis_info->print_address_func) (addr, dis_info);
    864       1.1     skrll 		  while (*ch && *ch != NEXT_IS_ADDR)
    865       1.1     skrll 		    ++ch;
    866       1.1     skrll 		  if (*ch)
    867       1.1     skrll 		    ++ch;
    868       1.1     skrll 		}
    869       1.1     skrll 	      else
    870       1.1     skrll 		(*dis_info->fprintf_func)(dis_info->stream, "%c", *ch++);
    871       1.1     skrll 	    }
    872                     	  if (argnum < maxarg)
    873                     	    (*dis_info->fprintf_func)(dis_info->stream, ", ");
    874                     	}
    875                         }
    876                       return aoffset / 8;
    877                     }
    878