home *** CD-ROM | disk | FTP | other *** search
/ C/C++ Users Group Library 1996 July / C-C++ Users Group Library July 1996.iso / vol_400 / 430_01 / m68kdis / utils.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-12-29  |  22.2 KB  |  1,037 lines

  1. /*
  2.  *                 Author:  Christopher G. Phillips
  3.  *              Copyright (C) 1994 All Rights Reserved
  4.  *
  5.  *                              NOTICE
  6.  *
  7.  * Permission to use, copy, modify, and distribute this software and
  8.  * its documentation for any purpose and without fee is hereby granted
  9.  * provided that the above copyright notice appear in all copies and
  10.  * that both the copyright notice and this permission notice appear in
  11.  * supporting documentation.
  12.  *
  13.  * The author makes no representations about the suitability of this
  14.  * software for any purpose.  This software is provided ``as is''
  15.  * without express or implied warranty.
  16.  */
  17.  
  18. /*
  19.  * Various utility functions including formatting effective addresses,
  20.  * reading input (correctly!), and printing are here.
  21.  */
  22.  
  23. #include <stdio.h>
  24. #include <stdlib.h>
  25. #include <stdarg.h>
  26. #include <string.h>
  27. #include <ctype.h>
  28. #include <math.h>
  29. #include <float.h>
  30. #include <limits.h>
  31. #include "dis.h"
  32.  
  33. /*
  34.  * Format immediate constant ``value'' into ``s''.
  35.  */
  36. int
  37. immsprintf(char *s, long value)
  38. {
  39.     long    absvalue;
  40.     char    *sign;
  41.  
  42.     if (pass == FIRSTPASS)
  43.         return 0;
  44.  
  45.     if (value < 0) {
  46.         absvalue = -value;
  47.         sign = "-$";
  48.     } else {
  49.         absvalue = value;
  50.         sign = "$";
  51.     }
  52.     if (absvalue > 9 || value == LONG_MIN)
  53.         return sprintf(s, "%ld!%s%lx", value, sign, absvalue);
  54.     else
  55.         return sprintf(s, "%ld", value);
  56. }
  57.  
  58. /*
  59.  * Sign-extend ``value'' from a ``bits''-bit value to a long.
  60.  */
  61. long
  62. signextend(long value, int bits)
  63. {
  64.     switch (bits) {
  65.     case 8:
  66.         value &= 0xff;
  67.         if (value & 0x80)
  68.             value |= ~0xffL;
  69.         break;
  70.     case 16:
  71.         value &= 0xffff;
  72.         if (value & 0x8000)
  73.             value |= ~0xffffL;
  74.         break;
  75.     case 32:
  76.         value &= 0xffffffff;
  77.         if (value & 0x80000000)
  78.             value |= ~0xffffffffL;
  79.         break;
  80.     }
  81.  
  82.     return value;
  83. }
  84.  
  85. char    instbuf[512];
  86. size_t    leninstbuf = 0;
  87.  
  88. /*
  89.  * Read a word from the input file.  Put its numerical value in *wp.
  90.  */
  91. int
  92. nextword(m68kword *wp)
  93. {
  94.     unsigned char    c[WORDSIZE];
  95.     size_t        i;
  96.  
  97.     if (fread(c, 1, WORDSIZE, infp) == WORDSIZE) {
  98.         for (*wp = 0, i = 0; i < WORDSIZE; i++)
  99.             *wp += c[i] << (CHAR_BIT * (WORDSIZE - 1 - i));
  100.         pc += WORDSIZE;
  101.         curoffset += WORDSIZE;
  102.         for (i = 0; i < WORDSIZE; i++) {
  103.             sprintf(&instbuf[leninstbuf], "%0*x", WORDSIZE, c[i]);
  104.             leninstbuf += WORDSIZE;
  105.         }
  106.         return 0;
  107.     } else
  108.         return -1;
  109. }
  110.  
  111. /*
  112.  * Get a sign-extended value of type ``size'' from the input file.
  113.  */
  114. long
  115. getval(int size, int *failure)
  116. {
  117.     m68kword    extra[2];
  118.     long        value;
  119.  
  120.     if (nextword(&extra[0]) == -1) {
  121.         *failure = -1;
  122.         return 0;
  123.     }
  124.     switch (size) {
  125.     case BYTE:
  126. #if 0
  127.         if (extra[0] & 0xff00) {
  128.             *failure = -1;
  129.             return 0;
  130.         } else
  131. #endif
  132.         value = signextend(extra[0], 8);
  133.         break;
  134.     case WORD:
  135.         value = signextend(extra[0], 16);
  136.         break;
  137.     case LONGWORD:
  138.         if (nextword(&extra[1]) == -1) {
  139.             *failure = -1;
  140.             return 0;
  141.         }
  142.         value = signextend(((long)extra[0] << 16) | extra[1], 32);
  143.         break;
  144.     default:
  145.         *failure = -1;
  146.         return 0;
  147.         break;
  148.     }
  149.  
  150.     *failure = 0;
  151.     return value;
  152. }
  153.  
  154. /*
  155.  * Translate scale bits to a scaling factor.
  156.  */
  157. static int
  158. scale(int s)
  159. {
  160.     switch (s) {
  161.     case 0:    return 1;    break;
  162.     case 1:    return 2;    break;
  163.     case 2:    return 4;    break;
  164.     case 3:    return 8;    break;
  165.     }
  166.  
  167.     /* NOTREACHED */
  168. }
  169.  
  170. /*
  171.  * Format address register ``reg'' taking ``sp'' into account.
  172.  */
  173. char *
  174. Areg(int reg)
  175. {
  176.     static char    s[2] = "A0";
  177.  
  178.     if (sp && reg == 7)
  179.         return "SP";
  180.     else {
  181.         s[1] = reg + '0';
  182.         return s;
  183.     }
  184. }
  185.  
  186. /*
  187.  * Format register ``reg''.
  188.  */
  189. void
  190. Areg2(char *s, char c, int reg)
  191. {
  192.     if (c == 'A')
  193.         sprintf(s, "%2.2s", Areg(reg));
  194.     else
  195.         sprintf(s, "D%d", reg);
  196. }
  197.  
  198. /*
  199.  * Extended mode for extension words.
  200.  *
  201.  * The formatted text goes in ``s''.
  202.  * Return 0 for success, negative for failure.
  203.  */
  204. static int
  205. extended(char *s, const char *reg, int size)
  206. {
  207.     m68kword    extra;
  208.     m68kaddr    bd;
  209.     m68kaddr    od;
  210.     m68kaddr    savedpc;
  211.     int        comma;
  212.     int        n = 0;
  213.     int        failure;
  214.     char        reg2[2];
  215.  
  216.     savedpc = pc;
  217.     if (nextword(&extra) == -1)
  218.         return -1;
  219.     if (CPU(chip) < MC68020 || (extra & 0x0100) == 0) {
  220.         /* Brief format */
  221.  
  222.         long    value;
  223.  
  224.         /*
  225.          * Format is as follows:
  226.          *
  227.          * Bits        Name
  228.          * 15        Index register type (D/A, 0 if D)
  229.          * 12-14    Index register number
  230.          * 11        Index size (W/L, 0 if sign-extended word)
  231.          * 9-10        Scale (00 = 1, 01 = 2, 10 = 4, 11 = 8)
  232.          * 8        Must be 0
  233.          * 0-7        Displacement
  234.          */
  235.  
  236.         if (CPU(chip) >= MC68020)
  237.             n += sprintf(s, "(");
  238.         value = (long)signextend(extra, 8);
  239.         if (strcmp(reg, "PC") == 0)
  240.             value += WORDSIZE;
  241.         n += immsprintf(s + n, value);
  242.         n += sprintf(s + n, "%s", (CPU(chip) < MC68020) ? "(" : ",");
  243.         Areg2(reg2, (extra & 0x8000) ? 'A' : 'D', (extra >> 12) & 7);
  244.         n += sprintf(s + n, "%s,%2.2s.%c", reg, reg2,
  245.           (extra & 0x0800) ? 'L' : 'W');
  246.         if (CPU(chip) >= MC68020 && ((extra >> 9) & 3))
  247.             n += sprintf(s + n, "*%d", scale((extra >> 9) & 3));
  248.         n += sprintf(s + n, ")");
  249.     } else {
  250.         /* Full format */
  251.  
  252.         /*
  253.          * Format is as follows:
  254.          *
  255.          * Bits        Name
  256.          * 15        Index register type (D/A, 0 if D)
  257.          * 12-14    Index register number
  258.          * 11        Index size (W/L, 0 if sign-extended word)
  259.          * 9-10        Scale (00 = 1, 01 = 2, 10 = 4, 11 = 8)
  260.          * 8        Must be 1
  261.          * 7        Base suppress (1 if base register suppressed)
  262.          * 6        Index suppress (1 if index register suppressed)
  263.          * 4-5        Base displacement size (00 = reserved,
  264.                   01 = null, 10 = word, 11 = long)
  265.          * 3        Must be 0
  266.          * 0-2        Index/Indirect selection
  267.  
  268.          * I/IS combinations:
  269.          *
  270.          * IS    I/IS    Operation
  271.          * 0    000    No memory indirection
  272.          * 0    001    Indirect preindexed with null outer displacement
  273.          * 0    010    Indirect preindexed with word od
  274.          * 0    011    Indirect preindexed with long od
  275.          * 0    101    Indirect postindexed with null od
  276.          * 0    110    Indirect postindexed with word od
  277.          * 0    111    Indirect postindexed with long od
  278.          * 1    000    No memory indirection
  279.          * 1    001    Memory indirect with null od
  280.          * 1    010    Memory indirect with word od
  281.          * 1    011    Memory indirect with long od
  282.          */
  283.  
  284.         /*
  285.          * Get base displacement
  286.          */
  287.         switch ((extra >> 4) & 3) {
  288.         case 0:
  289.             return -1;
  290.             break;
  291.         case 1:
  292.             bd = 0;
  293.             break;
  294.         case 2:
  295.             bd = getval(WORD, &failure);
  296.             if (failure)
  297.                 return failure;
  298.             break;
  299.         case 3:
  300.             bd = getval(LONGWORD, &failure);
  301.             if (failure)
  302.                 return failure;
  303.             break;
  304.         }
  305.  
  306.         /*
  307.          * Check if collapses to PC-relative
  308.          */
  309.         if ((extra & 0x01cf) == 0x0140) {
  310.             if (pass == DCLABELSPASS) {
  311.                 if (bd + savedpc >= initialpc
  312.                   && bd + savedpc <= initialpc + maxoffset) {
  313.                     insts[bd + savedpc - initialpc].flags
  314.                       |= ISLABEL;
  315.                     if (!insts[ppc - initialpc].size &&
  316.                       insts[ppc - initialpc].flags & ISFPU)
  317.                         insts[bd + savedpc
  318.                           - initialpc].flags
  319.                           |= ftype2lis(size);
  320.                 }
  321.             } else if (pass == FIRSTPASS && pcrelative) {
  322.                 required[flags & 3] = bd + savedpc;
  323.                 flags++;
  324.             } else if (pass == LASTPASS
  325.               && bd + savedpc >= initialpc
  326.               && bd + savedpc <= initialpc + maxoffset
  327.               && insts[bd + savedpc - initialpc].labelnum)
  328.                 sprintf(s, "L%d",
  329.                  insts[bd + savedpc - initialpc].labelnum);
  330.             else /* if ((pass == FIRSTPASS || pass == LASTPASS)
  331.               && !pcrelative
  332.               || pass == DEBUGPASS
  333.               || pass == LASTPASS && pcrelative
  334.               && bd + savedpc > initialpc + maxoffset) */ {
  335.                 if (bd)
  336.                     sprintf(s, "(%ld,PC)!$%lx", bd,
  337.                       bd + savedpc);
  338.                 else
  339.                     sprintf(s, "(PC)!$%lx", savedpc);
  340.             }
  341.  
  342.             return 0;
  343.         }
  344.  
  345.         switch (extra & 3) {
  346.         case 0: /* FALLTHROUGH */
  347.         case 1:
  348.             od = 0;
  349.             break;
  350.         case 2:
  351.             od = getval(WORD, &failure);
  352.             if (failure)
  353.                 return failure;
  354.             break;
  355.         case 3:
  356.             od = getval(LONGWORD, &failure);
  357.             if (failure)
  358.                 return failure;
  359.             break;
  360.         }
  361.         n += sprintf(s + n, "(");
  362.         if (extra & 3)
  363.             n += sprintf(s + n, "[");
  364.         if (comma = bd)
  365.             n += immsprintf(s + n, (long)bd);
  366.         if ((extra & 0x0080) == 0) {
  367.             /*
  368.              * Base suppress is 0.
  369.              */
  370.             if (comma)
  371.                 n += sprintf(s + n, ",");
  372.             n += sprintf(s + n, "%s", reg);
  373.             comma = 1;
  374.         } else if (strcmp(reg, "PC") == 0) {
  375.             if (comma)
  376.                 n += sprintf(s + n, ",");
  377.             n += sprintf(s + n, "ZPC");
  378.             comma = 1;
  379.         }
  380.         if (extra & 4) {
  381.             n += sprintf(s + n, "]");
  382.             comma = 1;
  383.         }
  384.         if ((extra & 0x0040) == 0) {
  385.             /*
  386.              * Index suppress is 0.
  387.              */
  388.             if ((extra & 7) == 4)
  389.                 return -1;
  390.             if (comma)
  391.                 n += sprintf(s + n, ",");
  392.             Areg2(reg2, (extra & 0x8000) ? 'A' : 'D',
  393.               (extra >> 12) & 7);
  394.             n += sprintf(s + n, "%2.2s.%c", reg2,
  395.               (extra & 0x0800) ? 'L' : 'W');
  396.             if ((extra >> 9) & 3)
  397.                 n += sprintf(s + n, "*%d",
  398.                   scale((extra >> 9) & 3));
  399.         } else if (extra & 4)
  400.             return -1;
  401.         if ((extra & 3) && (extra & 4) == 0) {
  402.             n += sprintf(s + n, "]");
  403.             comma = 1;
  404.         }
  405.         if (od) {
  406.             if (comma)
  407.                 n += sprintf(s + n, ",");
  408.             n += immsprintf(s + n, (long)od);
  409.         }
  410.         if (n) {
  411.             if (s[n - 1] != '(')
  412.                 n += sprintf(s + n, ")");
  413.             else {
  414.                 s[n - 1] = '\0';
  415.                 if (--n == 0)
  416.                     sprintf(s, "0");
  417.             }
  418.         } else
  419.             sprintf(s, "0");
  420.     }
  421.  
  422.     return 0;
  423. }
  424.  
  425. /*
  426.  * The next few functions convert hexadecimal nibble values
  427.  * to a floating-point value (and format it).
  428.  */
  429.  
  430. #define BIT(p,n)        ((p)[(n) / 32] & (1UL << (32 - (n) % 32 - 1)))
  431.  
  432. /*
  433.  * Is the mantissa zero?
  434.  */
  435. static int
  436. zeromantissa(u32bit_t *p, size_t firstbit, size_t lastbit)
  437. {
  438.     size_t    bit;
  439.  
  440.     for (bit = firstbit; bit <= lastbit; bit++)
  441.         if (BIT(p, bit))
  442.             return 0;
  443.  
  444.     return 1;
  445. }
  446.  
  447. /*
  448.  * Convert the input data in *lwp from bits ``firstbit'' to ``lastbit''
  449.  * into a mantissa.  Note that the *highest* bit is considered bit 0 here.
  450.  */
  451. static double
  452. stod(u32bit_t *lwp, size_t firstbit, size_t lastbit)
  453. {
  454.     double        result = 1.0;
  455.     double        value = 0.5;
  456.     size_t        bit;
  457.  
  458.     for (bit = firstbit; bit <= lastbit && value; bit++) {
  459.         if (BIT(lwp, bit))
  460.             result += value;
  461.         value /= 2.0;
  462.     }
  463.  
  464.     return result;
  465. }
  466.  
  467. /*
  468.  * Convert the input data in *longwords into a floating-point value
  469.  * of floating-point type ``type'' and place a human-readable version in ``s''.
  470.  * Return -1 if NaN or Denormalized, else 0.
  471.  */
  472. int
  473. fpoint(u32bit_t *longwords, int type, char *s)
  474. {
  475.     short    exponent;
  476.     short    sign;
  477.     short    zero;
  478.     short    maxexp;
  479.     short    minexp;
  480.     size_t    firstbit;
  481.     size_t    lastbit;
  482.     int    rval = 0;    /* return -1 if NaN or Denormalized */
  483.  
  484.     /* These are for PACKED */
  485.     short    mantissa[17];
  486.     short    lastnonzero;
  487.     short    firstnonzero;
  488.     size_t    i;
  489.  
  490.     sign = (longwords[0] & 0x80000000) != 0;
  491.  
  492.     switch (type) {
  493.     case SINGLE:
  494.         /*
  495.          * Format:
  496.          *
  497.          * 1 bit    sign
  498.          * 8 bits    exponent (biased by 0x7f)
  499.          * 23 bits    mantissa (implicit leading bit
  500.          *              left of implied binary point)
  501.          */
  502.         exponent = ((longwords[0] >> (32 - (8+1))) & 0xff) - 0x7f;
  503.         firstbit = 31 - 22;
  504.         lastbit = 31;
  505.         zero = zeromantissa(longwords, firstbit, lastbit);
  506.         maxexp = 0x80;
  507.         minexp = -0x7f;
  508.         break;
  509.     case DOUBLE:
  510.         /*
  511.          * Format:
  512.          *
  513.          * 1 bit    sign
  514.          * 11 bits    exponent (biased by 0x3ff)
  515.          * 52 bits    mantissa (implicit leading bit
  516.          *              left of implied binary point)
  517.          */
  518.         exponent = ((longwords[0] >> (32 - (11+1))) & 0x7ff) - 0x3ff;
  519.         firstbit = 63 - 51;
  520.         lastbit = 63;
  521.         zero = zeromantissa(longwords, firstbit, lastbit);
  522.         maxexp = 0x400;
  523.         minexp = -0x3ff;
  524.         break;
  525.     case EXTENDED:
  526.         /*
  527.          * Format:
  528.          *
  529.          * 1 bit    sign
  530.          * 15 bits    exponent (biased by 0x3fff)
  531.          * 16 bits    unused
  532.          * 1 bit    explicit leading bit
  533.          *        left of binary point
  534.          * <binary point>
  535.          * 63 bits    mantissa (implicit leading bit
  536.          *              left of implied binary point)
  537.          */
  538.         exponent = ((longwords[0] >> (32 - (15+1))) & 0x7fff) - 0x3fff;
  539.         firstbit = 95 - 62;
  540.         lastbit = 95;
  541.         zero = zeromantissa(longwords, firstbit, lastbit);
  542.         maxexp = 0x4000;
  543.         minexp = -0x3fff;
  544.         break;
  545.     case PACKED:
  546.         /*
  547.          * Format:
  548.          *
  549.          * 1 bit    sign
  550.          * 1 bit    sign of exponent
  551.          * 2 bits    sign of exponent
  552.          * 12 bits    3-digit exponent
  553.          * 12 bits    unused
  554.          * 4 bits    explicit leading digit left of decimal point
  555.          * <decimal point>
  556.          * 64 bits    16-digit (17 with leading digit) mantissa
  557.          */
  558.         zero = 1;
  559.         firstnonzero = -1;
  560.         for (i = 0; i < 17; i++) {
  561.             mantissa[i] = longwords[(i + 7) / 8]
  562.               >> (((24 - i) % 8) * 4) & 0xf;
  563.             if (mantissa[i]) {
  564.                 zero = 0;
  565.                 lastnonzero = i;
  566.                 if (firstnonzero == -1)
  567.                     firstnonzero = i;
  568.             }
  569.             if (mantissa[i] > 9)
  570.                 rval = -1;
  571.         }
  572.         exponent = ((longwords[0] >> 80 % 32) & 0xf)
  573.           + ((longwords[0] >> 84 % 32) & 0xf) * 10
  574.           + ((longwords[0] >> 88 % 32) & 0xf) * 100;
  575.         if (((longwords[0] >> 80 % 32) & 0xf) > 9
  576.           || ((longwords[0] >> 84 % 32) & 0xf) > 9
  577.           || ((longwords[0] >> 88 % 32) & 0xf) > 9)
  578.             rval = -1;
  579.         if (longwords[0] & 0x40000000)
  580.             exponent = -exponent;
  581.         exponent -= firstnonzero;
  582.         break;
  583.     }
  584.  
  585.     if (type != PACKED && exponent == maxexp
  586.       || type == PACKED && (longwords[0] & 0x7fff0000) == 0x7fff0000) {
  587.         if (zero) {
  588.             /* Infinity */
  589.             if (sign)
  590.                 *s++ = '-';
  591.             strcpy(s, "INF");
  592.         } else {
  593.             /* NaN */
  594.             strcpy(s, "NaN");
  595.         }
  596.     } else if (type != PACKED && exponent == minexp
  597.       || type == PACKED && zero) {
  598.         if (zero) {
  599.             /* Zero */
  600.             strcpy(s, "#0");
  601.         } else {
  602.             /* Denormalized */
  603.             strcpy(s, "Denormalized");
  604.             rval = -1;
  605.         }
  606.     } else if (type != PACKED) {
  607.         /* Normalized */
  608.  
  609.         double    dmantissa;
  610.  
  611.         dmantissa = stod(longwords, firstbit, lastbit);
  612.         if (type == EXTENDED && BIT(longwords, firstbit - 1) == 0) {
  613.             /* Unnormalized */
  614.             dmantissa -= 1.0;
  615.             while (dmantissa < 1.0) {
  616.                 dmantissa *= 2.0;
  617.                 exponent--;
  618.             }
  619.         }
  620.  
  621.         *s++ = '#';
  622.         if (sign)
  623.             *s++ = '-';
  624.  
  625.         /*
  626.          * We need to determine if dmantissa * 2^exponent
  627.          * is within range or not.
  628.          */
  629.         if (exponent < DBL_MAX_EXP && exponent > DBL_MIN_EXP
  630.           || exponent == DBL_MAX_EXP
  631.           && dmantissa <= DBL_MAX / pow(2.0, DBL_MAX_EXP)
  632.           || exponent == DBL_MIN_EXP
  633.           && dmantissa <= DBL_MIN / pow(2.0, DBL_MIN_EXP)
  634.           ) {
  635.             if (exponent)
  636.                 dmantissa *= pow(2.0, exponent);
  637.             sprintf(s, "%.*g", fdigits, dmantissa);
  638.         } else {
  639.             double    exp10;
  640.             double    log10value;
  641.  
  642.             log10value = log10(dmantissa)
  643.               + 0.30102999566398119521 * log10(exponent);
  644.             exp10 = floor(log10value);
  645.             dmantissa = pow(10.0, log10value - exp10);
  646.             s += sprintf(s, "%.*g", fdigits, dmantissa);
  647.             if (exp10)
  648.                 sprintf(s, "e%d", dmantissa, (int)exp10);
  649.         }
  650.     } else /* type == PACKED */ {
  651.         *s++ = '#';
  652.         if (sign)
  653.             *s++ = '-';
  654.         s += sprintf(s, "%x", mantissa[firstnonzero]);
  655.         if (lastnonzero != firstnonzero)
  656.             *s++ = '.';
  657.         for (i = firstnonzero + 1; i <= lastnonzero; i++)
  658.             s += sprintf(s, "%x", mantissa[i]);
  659.     
  660.         if (exponent)
  661.             sprintf(s, "e%d", exponent);
  662.     }
  663.  
  664.     return rval;
  665. }
  666.  
  667. /*
  668.  * Read input bytes for floating-point constant
  669.  * of floating-point type ``type''. Put formatted value in ``s''.
  670.  */
  671. static int
  672. memfpoint(char *s, int type)
  673. {
  674.     u32bit_t    longwords[3];
  675.     size_t        nlongwords;
  676.     int    failure;
  677.     size_t    i;
  678.  
  679.     switch (type) {
  680.     case SINGLE:    nlongwords = 1;    break;
  681.     case DOUBLE:    nlongwords = 2;    break;
  682.     case EXTENDED: case PACKED:
  683.             nlongwords = 3;    break;
  684.     }
  685.  
  686.     for (i = 0; i < nlongwords; i++) {
  687.         longwords[i] = getval(LONGWORD, &failure);
  688.         if (failure)
  689.             return failure;
  690.     }
  691.  
  692.     return fpoint(longwords, type, s);
  693. }
  694.  
  695. /*
  696.  * Find effective address given mode/register combination and instruction size.
  697.  * Result goes in ``s''.  Return 0 for success, else negative.
  698.  */
  699. int
  700. getea(char *s, int reg, int mode, int size)
  701. {
  702.     long        longval;
  703.     m68kaddr    savedpc;
  704.     char        creg[3];
  705.     int        failure;
  706.  
  707.     switch (mode) {
  708.     case 0:
  709.         /* Data register direct */
  710.         sprintf(s, "D%d", reg);
  711.         break;
  712.     case 1:
  713.         /* Address register direct */
  714.         sprintf(s, "%2.2s", Areg(reg));
  715.         break;
  716.     case 2:
  717.         /* Address register indirect */
  718.         sprintf(s, "(%2.2s)", Areg(reg));
  719.         break;
  720.     case 3:
  721.         /* Address register indirect with postincrement */
  722.         sprintf(s, "(%2.2s)+", Areg(reg));
  723.         break;
  724.     case 4:
  725.         /* Address register indirect with predecrement */
  726.         sprintf(s, "-(%2.2s)", Areg(reg));
  727.         break;
  728.     case 5:
  729.         /* Address register indirect with displacement */
  730.         longval = getval(WORD, &failure);
  731.         if (failure)
  732.             return failure;
  733.         if (CPU(chip) >= MC68020)
  734.             sprintf(s, "(%ld,%2.2s)", longval, Areg(reg));
  735.         else
  736.             sprintf(s, "%ld(%2.2s)", longval, Areg(reg));
  737.         break;
  738.     case 6:
  739.         /*
  740.          * Address register indirect
  741.          * with index and displacement
  742.          */
  743.         sprintf(creg, "%2.2s", Areg(reg));
  744.         return extended(s, creg, size);
  745.         break;
  746.     case 7:
  747.         switch (reg) {
  748.         case 0:
  749.             /* Absolute short */
  750.             longval = getval(WORD, &failure);
  751.             if (failure)
  752.                 return failure;
  753.             sprintf(s, "$%0*lx.W", 2 * WORDSIZE, longval);
  754.             break;
  755.         case 1:
  756.             /* Absolute long */
  757.             longval = getval(LONGWORD, &failure);
  758.             if (failure)
  759.                 return failure;
  760.             sprintf(s, "$%0*lx.L", 4 * WORDSIZE, longval);
  761.             break;
  762.         case 2:
  763.             /* Program counter indirect with displacement */
  764.             savedpc = pc;
  765.             longval = getval(WORD, &failure);
  766.             if (failure)
  767.                 return failure;
  768.  
  769.             if (pass == DCLABELSPASS) {
  770.                 if (longval + savedpc >= initialpc
  771.                   && longval + savedpc <= initialpc
  772.                   + maxoffset) {
  773.                     insts[longval + savedpc
  774.                       - initialpc].flags |= ISLABEL;
  775.                     if (!insts[longval + savedpc
  776.                       - initialpc].size &&
  777.                       insts[ppc - initialpc].flags & ISFPU)
  778.                         insts[longval + savedpc
  779.                           - initialpc].flags
  780.                           |= ftype2lis(size);
  781.                 }
  782.             } else if (pass == FIRSTPASS && pcrelative) {
  783.                 required[flags & 3] = longval + savedpc;
  784.                 flags++;
  785.             } else if (pass == LASTPASS
  786.               && longval + savedpc >= initialpc
  787.               && longval + savedpc <= initialpc + maxoffset
  788.               && insts[longval + savedpc - initialpc].labelnum)
  789.                 sprintf(s, "L%d",
  790.                  insts[longval + savedpc - initialpc].labelnum);
  791.             else /* if ((pass == FIRSTPASS || pass == LASTPASS)
  792.               && !pcrelative
  793.               || pass == DEBUGPASS
  794.               || pass == LASTPASS && pcrelative
  795.               && longval + savedpc > initialpc + maxoffset) */ {
  796.                 if (longval == 0)
  797.                     sprintf(s, "(PC)!$%lx", savedpc);
  798.                 else if (CPU(chip) >= MC68020)
  799.                     sprintf(s, "(%ld,PC)!$%lx", longval,
  800.                       longval + savedpc);
  801.                 else
  802.                     sprintf(s, "%ld(PC)!$%lx", longval,
  803.                       longval + savedpc);
  804.             }
  805.             break;
  806.         case 3:
  807.             /*
  808.              * Program counter indirect
  809.              * with index and displacement
  810.              */
  811.             return extended(s, "PC", size);
  812.             break;
  813.         case 4:
  814.             /* Immediate */
  815.             switch (size) {
  816.             case BYTE:    /* FALLTHROUGH */
  817.             case WORD:    /* FALLTHROUGH */
  818.             case LONGWORD:    /* FALLTHROUGH */
  819.             case DOUBLELONGWORD:
  820.                 s[0] = '#';
  821.                 longval = getval(size == DOUBLELONGWORD
  822.                   ? LONGWORD : size, &failure);
  823.                 if (failure)
  824.                     return failure;
  825.                 s += immsprintf(s + 1, longval) + 1;
  826.                 if (size == DOUBLELONGWORD) {
  827.                     s[0] = '/';
  828.                     longval = getval(LONGWORD, &failure);
  829.                     if (failure)
  830.                         return failure;
  831.                     immsprintf(s + 1, longval);
  832.                 }
  833.                 break;
  834.             case SINGLE:    /* FALLTHROUGH */
  835.             case DOUBLE:    /* FALLTHROUGH */
  836.             case EXTENDED:    /* FALLTHROUGH */
  837.             case PACKED:
  838.                 (void)memfpoint(s, size);
  839.             }
  840.             break;
  841.         default:
  842.             return -1;
  843.         }
  844.     }
  845.  
  846.     return 0;
  847. }
  848.  
  849. /*
  850.  * If printing is appropriate, print an output line.
  851.  * The instruction name is given in ``name'' and ``lflags'' tells about
  852.  * the instruction operands (the ellipsis arguments).
  853.  */
  854. void
  855. instprint(int lflags, const char *name, ...)
  856. {
  857.     va_list ap;
  858.     int    operands = f2ops(lflags);
  859.     char    *cp;
  860.     size_t    i;
  861.     int    tabs;
  862.  
  863.     va_start(ap, name);
  864.  
  865.     if (pass == LASTPASS || pass == DEBUGPASS) {
  866.         fprintf(outfp, "%08x", (int)ppc);
  867.         if (lower)
  868.             for (i = 0; i < leninstbuf; i++)
  869.                 instbuf[i] = tolower(instbuf[i]);
  870.         fprintf(outfp, "   %.*s", (int)leninstbuf, instbuf);
  871. #define TABSIZE    8
  872.         if (leninstbuf > 36 - TABSIZE)
  873.             tabs = 1;
  874.         else
  875.             tabs = (36 - leninstbuf) / TABSIZE;
  876.         while (tabs--)
  877.             (void)putc('\t', outfp);
  878. #undef TABSIZE
  879.  
  880.         if (pass == LASTPASS && insts[ppc - initialpc].labelnum)
  881.             fprintf(outfp, "L%d", insts[ppc - initialpc].labelnum);
  882.         (void)putc('\t', outfp);
  883.         if (lower) {
  884.             char    *newname;
  885.             size_t    len = strlen(name);
  886.  
  887.             if (newname = malloc(len + 1)) {
  888.                 for (i = 0; i < len; i++)
  889.                     newname[i] = tolower(name[i]);
  890.                 newname[len] = '\0';
  891.                 fprintf(outfp, "%s", newname);
  892.                 free(newname);
  893.             } else
  894.                 fprintf(outfp, "%s", name);
  895.         } else
  896.             fprintf(outfp, "%s", name);
  897.         if (lower) {
  898.             if (lflags & PBYTE)
  899.                 fprintf(outfp, ".b");
  900.             else if (lflags & PWORD)
  901.                 fprintf(outfp, ".w");
  902.             else if (lflags & PLONGWORD)
  903.                 fprintf(outfp, ".l");
  904.             else if (lflags & PDOUBLELONGWORD)
  905.                 fprintf(outfp, ".dl");
  906.             else if (lflags & PSINGLE)
  907.                 fprintf(outfp, ".s");
  908.             else if (lflags & PDOUBLE)
  909.                 fprintf(outfp, ".d");
  910.             else if (lflags & PEXTENDED)
  911.                 fprintf(outfp, ".x");
  912.             else if (lflags & PPACKED)
  913.                 fprintf(outfp, ".p");
  914.         } else {
  915.             if (lflags & PBYTE)
  916.                 fprintf(outfp, ".B");
  917.             else if (lflags & PWORD)
  918.                 fprintf(outfp, ".W");
  919.             else if (lflags & PLONGWORD)
  920.                 fprintf(outfp, ".L");
  921.             else if (lflags & PDOUBLELONGWORD)
  922.                 fprintf(outfp, ".DL");
  923.             else if (lflags & PSINGLE)
  924.                 fprintf(outfp, ".S");
  925.             else if (lflags & PDOUBLE)
  926.                 fprintf(outfp, ".D");
  927.             else if (lflags & PEXTENDED)
  928.                 fprintf(outfp, ".X");
  929.             else if (lflags & PPACKED)
  930.                 fprintf(outfp, ".P");
  931.         }
  932.     
  933.         for (i = 1; i <= operands; i++) {
  934.             putc(i == 1 ? '\t' : ',', outfp);
  935.             if (lflags & sharp2f(i))
  936.                 putc('#', outfp);
  937.             cp = va_arg(ap, char *);
  938.             if (lower && (cp[0] != 'L' || !isdigit(cp[1]))) {
  939.                 char    *cp2 = cp - 1;
  940.  
  941.                 while (*++cp2)
  942.                     *cp2 = tolower(*cp2);
  943.             }
  944.             fprintf(outfp, "%s", cp);
  945.         }
  946.         putc('\n', outfp);
  947.     }
  948.  
  949.     leninstbuf = 0;
  950.     ppc = pc;
  951.  
  952.     va_end(ap);
  953. }
  954.  
  955. /*
  956.  * Format a range of registers (``low'' to ``high'')
  957.  * into ``s'', beginning with a ``slash'' if necessary.
  958.  * ``ad'' specifies either address (A) or data (D) registers.
  959.  */
  960. static char *
  961. regwrite(char *s, char *ad, int low, int high, int slash)
  962. {
  963.     if (slash)
  964.         *s++ = '/';
  965.     if (high - low > 1) {
  966.         s += sprintf(s, "%s", ad);
  967.         *s++ = low + '0';
  968.         *s++ = '-';
  969.         s += sprintf(s, "%s", ad);
  970.         *s++ = high + '0';
  971.     } else if (high - low == 1) {
  972.         s += sprintf(s, "%s", ad);
  973.         *s++ = low + '0';
  974.         *s++ = '/';
  975.         s += sprintf(s, "%s", ad);
  976.         *s++ = high + '0';
  977.     } else {
  978.         s += sprintf(s, "%s", ad);
  979.         *s++ = high + '0';
  980.     }
  981.     *s = '\0';
  982.  
  983.     return s;
  984. }
  985.  
  986. /*
  987.  * Format ``regmask'' into ``s''.  ``ad'' is a prefix used to indicate
  988.  * whether the mask is for address, data, or floating-point registers.
  989.  */
  990. char *
  991. regbyte(char *s, unsigned char regmask, char *ad, int doslash)
  992. {
  993.     int    i;
  994.     int    last;
  995.  
  996.     for (last = -1, i = 0; regmask; i++, regmask >>= 1)
  997.         if (regmask & 1) {
  998.             if (last != -1)
  999.                 continue;
  1000.             else
  1001.                 last = i;
  1002.         } else if (last != -1) {
  1003.             s = regwrite(s, ad, last, i - 1, doslash);
  1004.             doslash = 1;
  1005.             last = -1;
  1006.         }
  1007.  
  1008.     if (last != -1)
  1009.         s = regwrite(s, ad, last, i - 1, doslash);
  1010.  
  1011.     return s;
  1012. }
  1013.  
  1014. /*
  1015.  * Reverse the ``nbits'' bits in ``bits''.
  1016.  * Used to change register masks.
  1017.  */
  1018. void
  1019. revbits(unsigned long *bits, size_t nbits)
  1020. {
  1021.     int    i;
  1022.     int    b1, b2;
  1023.  
  1024.     for (i = 0; i < nbits / 2; i++) {
  1025.         b1 = *bits & (1 << i);
  1026.         b2 = *bits & (1 << (nbits - 1 - i));
  1027.         if (b1)
  1028.             *bits |= 1 << (nbits - 1 - i);
  1029.         else
  1030.             *bits &= ~(1 << (nbits - 1 - i));
  1031.         if (b2)
  1032.             *bits |= 1 << i;
  1033.         else
  1034.             *bits &= ~(1 << i);
  1035.     }
  1036. }
  1037.