home *** CD-ROM | disk | FTP | other *** search
/ Geek Gadgets 1 / ADE-1.bin / ade-dist / binutils-2.7-src.tgz / tar.out / fsf / binutils / opcodes / m68k-dis.c < prev    next >
C/C++ Source or Header  |  1996-09-28  |  28KB  |  1,144 lines

  1. /* Print Motorola 68k instructions.
  2.    Copyright 1986, 1987, 1989, 1991, 1992, 1993 Free Software Foundation, Inc.
  3.  
  4. This file is free software; you can redistribute it and/or modify
  5. it under the terms of the GNU General Public License as published by
  6. the Free Software Foundation; either version 2 of the License, or
  7. (at your option) any later version.
  8.  
  9. This program is distributed in the hope that it will be useful,
  10. but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  12. GNU General Public License for more details.
  13.  
  14. You should have received a copy of the GNU General Public License
  15. along with this program; if not, write to the Free Software
  16. Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
  17.  
  18. #include "dis-asm.h"
  19. #include "floatformat.h"
  20.  
  21. #include "opcode/m68k.h"
  22.  
  23. /* Local function prototypes */
  24.  
  25. static int
  26. fetch_arg PARAMS ((unsigned char *, int, int, disassemble_info *));
  27.  
  28. static void
  29. print_base PARAMS ((int, bfd_vma, disassemble_info*));
  30.  
  31. static unsigned char *
  32. print_indexed PARAMS ((int, unsigned char *, bfd_vma, disassemble_info *));
  33.  
  34. static int
  35. print_insn_arg PARAMS ((const char *, unsigned char *, unsigned char *,
  36.             bfd_vma, disassemble_info *));
  37.  
  38. CONST char * CONST fpcr_names[] = {
  39.   "", "%fpiar", "%fpsr", "%fpiar/%fpsr", "%fpcr",
  40.   "%fpiar/%fpcr", "%fpsr/%fpcr", "%fpiar/%fpsr/%fpcr"};
  41.  
  42. static char *const reg_names[] = {
  43.   "%d0", "%d1", "%d2", "%d3", "%d4", "%d5", "%d6", "%d7",
  44.   "%a0", "%a1", "%a2", "%a3", "%a4", "%fp", "%a6", "%sp",
  45.   "%ps", "%pc"};
  46.  
  47. /* Sign-extend an (unsigned char). */
  48. #if __STDC__ == 1
  49. #define COERCE_SIGNED_CHAR(ch) ((signed char)(ch))
  50. #else
  51. #define COERCE_SIGNED_CHAR(ch) ((int)(((ch) ^ 0x80) & 0xFF) - 128)
  52. #endif
  53.  
  54. /* Get a 1 byte signed integer.  */
  55. #define NEXTBYTE(p)  (p += 2, FETCH_DATA (info, p), COERCE_SIGNED_CHAR(p[-1]))
  56.  
  57. /* Get a 2 byte signed integer.  */
  58. #define COERCE16(x) ((int) (((x) ^ 0x8000) - 0x8000))
  59. #define NEXTWORD(p)  \
  60.   (p += 2, FETCH_DATA (info, p), \
  61.    COERCE16 ((p[-2] << 8) + p[-1]))
  62.  
  63. /* Get a 4 byte signed integer.  */
  64. #define COERCE32(x) ((int) (((x) ^ 0x80000000) - 0x80000000))
  65. #define NEXTLONG(p)  \
  66.   (p += 4, FETCH_DATA (info, p), \
  67.    (COERCE32 ((((((p[-4] << 8) + p[-3]) << 8) + p[-2]) << 8) + p[-1])))
  68.  
  69. /* NEXTSINGLE and NEXTDOUBLE handle alignment problems, but not
  70.  * byte-swapping or other float format differences.  FIXME! */
  71.  
  72. union number {
  73.     double d;
  74.     float f;
  75.     char c[10];
  76. };
  77.  
  78. #define NEXTSINGLE(val, p) \
  79.   { unsigned int i; union number u;\
  80.     FETCH_DATA (info, p + sizeof (float));\
  81.     for (i = 0; i < sizeof(float); i++) u.c[i] = *p++; \
  82.     val = u.f; }
  83.  
  84. #define NEXTDOUBLE(val, p) \
  85.   { unsigned int i; union number u;\
  86.     FETCH_DATA (info, p + sizeof (double));\
  87.     for (i = 0; i < sizeof(double); i++) u.c[i] = *p++; \
  88.     val = u.d; }
  89.  
  90. /* Need a function to convert from extended to double precision... */
  91. #define NEXTEXTEND(p) \
  92.   (p += 12, FETCH_DATA (info, p), 0.0)
  93.  
  94. /* Need a function to convert from packed to double
  95.    precision.   Actually, it's easier to print a
  96.    packed number than a double anyway, so maybe
  97.    there should be a special case to handle this... */
  98. #define NEXTPACKED(p) \
  99.   (p += 12, FETCH_DATA (info, p), 0.0)
  100.  
  101.  
  102. /* Maximum length of an instruction.  */
  103. #define MAXLEN 22
  104.  
  105. #include <setjmp.h>
  106.  
  107. struct private
  108. {
  109.   /* Points to first byte not fetched.  */
  110.   bfd_byte *max_fetched;
  111.   bfd_byte the_buffer[MAXLEN];
  112.   bfd_vma insn_start;
  113.   jmp_buf bailout;
  114. };
  115.  
  116. /* Make sure that bytes from INFO->PRIVATE_DATA->BUFFER (inclusive)
  117.    to ADDR (exclusive) are valid.  Returns 1 for success, longjmps
  118.    on error.  */
  119. #define FETCH_DATA(info, addr) \
  120.   ((addr) <= ((struct private *)(info->private_data))->max_fetched \
  121.    ? 1 : fetch_data ((info), (addr)))
  122.  
  123. static int
  124. fetch_data (info, addr)
  125.      struct disassemble_info *info;
  126.      bfd_byte *addr;
  127. {
  128.   int status;
  129.   struct private *priv = (struct private *)info->private_data;
  130.   bfd_vma start = priv->insn_start + (priv->max_fetched - priv->the_buffer);
  131.  
  132.   status = (*info->read_memory_func) (start,
  133.                       priv->max_fetched,
  134.                       addr - priv->max_fetched,
  135.                       info);
  136.   if (status != 0)
  137.     {
  138.       (*info->memory_error_func) (status, start, info);
  139.       longjmp (priv->bailout, 1);
  140.     }
  141.   else
  142.     priv->max_fetched = addr;
  143.   return 1;
  144. }
  145.  
  146. /* This function is used to print to the bit-bucket. */
  147. static int
  148. #ifdef __STDC__
  149. dummy_printer (FILE * file, const char * format, ...)
  150. #else
  151. dummy_printer (file) FILE *file;
  152. #endif
  153.  { return 0; }
  154.  
  155. void
  156. dummy_print_address (vma, info)
  157.      bfd_vma vma;
  158.      struct disassemble_info *info;
  159. {
  160. }
  161.  
  162. /* Print the m68k instruction at address MEMADDR in debugged memory,
  163.    on INFO->STREAM.  Returns length of the instruction, in bytes.  */
  164.  
  165. int
  166. print_insn_m68k (memaddr, info)
  167.      bfd_vma memaddr;
  168.      disassemble_info *info;
  169. {
  170.   register int i;
  171.   register unsigned char *p;
  172.   unsigned char *save_p;
  173.   register const char *d;
  174.   register unsigned long bestmask;
  175.   const struct m68k_opcode *best = 0;
  176.   struct private priv;
  177.   bfd_byte *buffer = priv.the_buffer;
  178.   fprintf_ftype save_printer = info->fprintf_func;
  179.   void (*save_print_address) PARAMS((bfd_vma, struct disassemble_info*))
  180.     = info->print_address_func;
  181.  
  182.   info->private_data = (PTR) &priv;
  183.   priv.max_fetched = priv.the_buffer;
  184.   priv.insn_start = memaddr;
  185.   if (setjmp (priv.bailout) != 0)
  186.     /* Error return.  */
  187.     return -1;
  188.  
  189.   bestmask = 0;
  190.   FETCH_DATA (info, buffer + 2);
  191.   for (i = 0; i < m68k_numopcodes; i++)
  192.     {
  193.       const struct m68k_opcode *opc = &m68k_opcodes[i];
  194.       unsigned long opcode = opc->opcode;
  195.       unsigned long match = opc->match;
  196.  
  197.       if (((0xff & buffer[0] & (match >> 24)) == (0xff & (opcode >> 24)))
  198.       && ((0xff & buffer[1] & (match >> 16)) == (0xff & (opcode >> 16)))
  199.       /* Only fetch the next two bytes if we need to.  */
  200.       && (((0xffff & match) == 0)
  201.           ||
  202.           (FETCH_DATA (info, buffer + 4)
  203.            && ((0xff & buffer[2] & (match >> 8)) == (0xff & (opcode >> 8)))
  204.            && ((0xff & buffer[3] & match) == (0xff & opcode)))
  205.           ))
  206.     {
  207.       /* Don't use for printout the variants of divul and divsl
  208.          that have the same register number in two places.
  209.          The more general variants will match instead.  */
  210.       for (d = opc->args; *d; d += 2)
  211.         if (d[1] == 'D')
  212.           break;
  213.  
  214.       /* Don't use for printout the variants of most floating
  215.          point coprocessor instructions which use the same
  216.          register number in two places, as above. */
  217.       if (*d == '\0')
  218.         for (d = opc->args; *d; d += 2)
  219.           if (d[1] == 't')
  220.         break;
  221.  
  222.       /* Don't match fmovel with more than one register; wait for
  223.              fmoveml.  */
  224.       if (*d == '\0')
  225.         {
  226.           for (d = opc->args; *d; d += 2)
  227.         {
  228.           if (d[0] == 's' && d[1] == '8')
  229.             {
  230.               int val;
  231.  
  232.               val = fetch_arg (buffer, d[1], 3, info);
  233.               if ((val & (val - 1)) != 0)
  234.             break;
  235.             }
  236.         }
  237.         }
  238.  
  239.       if (*d == '\0' && match > bestmask)
  240.         {
  241.           best = opc;
  242.           bestmask = match;
  243.         }
  244.     }
  245.     }
  246.  
  247.   if (best == 0)
  248.     goto invalid;
  249.  
  250.   /* Point at first word of argument data,
  251.      and at descriptor for first argument.  */
  252.   p = buffer + 2;
  253.   
  254.   /* Figure out how long the fixed-size portion of the instruction is.
  255.      The only place this is stored in the opcode table is
  256.      in the arguments--look for arguments which specify fields in the 2nd
  257.      or 3rd words of the instruction.  */
  258.   for (d = best->args; *d; d += 2)
  259.     {
  260.       /* I don't think it is necessary to be checking d[0] here; I suspect
  261.      all this could be moved to the case statement below.  */
  262.       if (d[0] == '#')
  263.     {
  264.       if (d[1] == 'l' && p - buffer < 6)
  265.         p = buffer + 6;
  266.       else if (p - buffer < 4 && d[1] != 'C' && d[1] != '8' )
  267.         p = buffer + 4;
  268.     }
  269.       if ((d[0] == 'L' || d[0] == 'l') && d[1] == 'w' && p - buffer < 4)
  270.     p = buffer + 4;
  271.       switch (d[1])
  272.     {
  273.     case '1':
  274.     case '2':
  275.     case '3':
  276.     case '7':
  277.     case '8':
  278.     case '9':
  279.     case 'i':
  280.       if (p - buffer < 4)
  281.         p = buffer + 4;
  282.       break;
  283.     case '4':
  284.     case '5':
  285.     case '6':
  286.       if (p - buffer < 6)
  287.         p = buffer + 6;
  288.       break;
  289.     default:
  290.       break;
  291.     }
  292.     }
  293.   /* Some opcodes like pflusha and lpstop are exceptions; they take no
  294.      arguments but are two words long.  Recognize them by looking at
  295.      the lower 16 bits of the mask.  */
  296.   if (p - buffer < 4 && (best->match & 0xFFFF) != 0)
  297.     p = buffer + 4;
  298.   
  299.   FETCH_DATA (info, p);
  300.   
  301.   d = best->args;
  302.  
  303.   /* We can the operands twice.  The first time we don't print anything,
  304.      but look for errors. */
  305.  
  306.   save_p = p;
  307.   info->print_address_func = dummy_print_address;
  308.   info->fprintf_func = (fprintf_ftype)dummy_printer;
  309.   for ( ; *d; d += 2)
  310.     {
  311.       int eaten = print_insn_arg (d, buffer, p, memaddr + p - buffer, info);
  312.       if (eaten >= 0)
  313.     p += eaten;
  314.       else if (eaten == -1)
  315.     goto invalid;
  316.       else
  317.     {
  318.       (*info->fprintf_func)(info->stream,
  319.                 "<internal error in opcode table: %s %s>\n",
  320.                 best->name,
  321.                 best->args);
  322.       goto invalid;
  323.     }
  324.  
  325.     }
  326.   p = save_p;
  327.   info->fprintf_func = save_printer;
  328.   info->print_address_func = save_print_address;
  329.  
  330.   d = best->args;
  331.  
  332.   (*info->fprintf_func) (info->stream, "%s", best->name);
  333.  
  334.   if (*d)
  335.     (*info->fprintf_func) (info->stream, " ");
  336.  
  337.   while (*d)
  338.     {
  339.       p += print_insn_arg (d, buffer, p, memaddr + p - buffer, info);
  340.       d += 2;
  341.       if (*d && *(d - 2) != 'I' && *d != 'k')
  342.     (*info->fprintf_func) (info->stream, ",");
  343.     }
  344.   return p - buffer;
  345.  
  346.  invalid:
  347.   /* Handle undefined instructions.  */
  348.   info->fprintf_func = save_printer;
  349.   info->print_address_func = save_print_address;
  350.   (*info->fprintf_func) (info->stream, "0%o",
  351.              (buffer[0] << 8) + buffer[1]);
  352.   return 2;
  353. }
  354.  
  355. /* Returns number of bytes "eaten" by the operand, or
  356.    return -1 if an invalid operand was found, or -2 if
  357.    an opcode tabe error was found. */
  358.  
  359. static int
  360. print_insn_arg (d, buffer, p0, addr, info)
  361.      const char *d;
  362.      unsigned char *buffer;
  363.      unsigned char *p0;
  364.      bfd_vma addr;        /* PC for this arg to be relative to */
  365.      disassemble_info *info;
  366. {
  367.   register int val = 0;
  368.   register int place = d[1];
  369.   register unsigned char *p = p0;
  370.   int regno;
  371.   register CONST char *regname;
  372.   register unsigned char *p1;
  373.   double flval;
  374.   int flt_p;
  375.  
  376.   switch (*d)
  377.     {
  378.     case 'c':        /* cache identifier */
  379.       {
  380.         static char *const cacheFieldName[] = { "nc", "dc", "ic", "bc" };
  381.         val = fetch_arg (buffer, place, 2, info);
  382.         (*info->fprintf_func) (info->stream, cacheFieldName[val]);
  383.         break;
  384.       }
  385.  
  386.     case 'a':        /* address register indirect only. Cf. case '+'. */
  387.       {
  388.         (*info->fprintf_func)
  389.       (info->stream,
  390.        "%s@",
  391.        reg_names [fetch_arg (buffer, place, 3, info) + 8]);
  392.         break;
  393.       }
  394.  
  395.     case '_':        /* 32-bit absolute address for move16. */
  396.       {
  397.         val = NEXTLONG (p);
  398.     (*info->print_address_func) (val, info);
  399.         break;
  400.       }
  401.  
  402.     case 'C':
  403.       (*info->fprintf_func) (info->stream, "%%ccr");
  404.       break;
  405.  
  406.     case 'S':
  407.       (*info->fprintf_func) (info->stream, "%%sr");
  408.       break;
  409.  
  410.     case 'U':
  411.       (*info->fprintf_func) (info->stream, "%%usp");
  412.       break;
  413.  
  414.     case 'J':
  415.       {
  416.     static const struct { char *name; int value; } names[]
  417.       = {{"%sfc", 0x000}, {"%dfc", 0x001}, {"%cacr", 0x002},
  418.          {"%tc",  0x003}, {"%itt0",0x004}, {"%itt1", 0x005},
  419.              {"%dtt0",0x006}, {"%dtt1",0x007}, {"%buscr",0x008},
  420.          {"%usp", 0x800}, {"%vbr", 0x801}, {"%caar", 0x802},
  421.          {"%msp", 0x803}, {"%ibsp", 0x804},
  422.  
  423.          /* Should we be calling this psr like we do in case 'Y'?  */
  424.          {"%mmusr",0x805},
  425.  
  426.              {"%urp", 0x806}, {"%srp", 0x807}, {"%pcr", 0x808}};
  427.  
  428.     val = fetch_arg (buffer, place, 12, info);
  429.     for (regno = sizeof names / sizeof names[0] - 1; regno >= 0; regno--)
  430.       if (names[regno].value == val)
  431.         {
  432.           (*info->fprintf_func) (info->stream, "%s", names[regno].name);
  433.           break;
  434.         }
  435.     if (regno < 0)
  436.       (*info->fprintf_func) (info->stream, "%d", val);
  437.       }
  438.       break;
  439.  
  440.     case 'Q':
  441.       val = fetch_arg (buffer, place, 3, info);
  442.       /* 0 means 8, except for the bkpt instruction... */
  443.       if (val == 0 && d[1] != 's')
  444.     val = 8;
  445.       (*info->fprintf_func) (info->stream, "#%d", val);
  446.       break;
  447.  
  448.     case 'M':
  449.       val = fetch_arg (buffer, place, 8, info);
  450.       if (val & 0x80)
  451.     val = val - 0x100;
  452.       (*info->fprintf_func) (info->stream, "#%d", val);
  453.       break;
  454.  
  455.     case 'T':
  456.       val = fetch_arg (buffer, place, 4, info);
  457.       (*info->fprintf_func) (info->stream, "#%d", val);
  458.       break;
  459.  
  460.     case 'D':
  461.       (*info->fprintf_func) (info->stream, "%s",
  462.                  reg_names[fetch_arg (buffer, place, 3, info)]);
  463.       break;
  464.  
  465.     case 'A':
  466.       (*info->fprintf_func)
  467.     (info->stream, "%s",
  468.      reg_names[fetch_arg (buffer, place, 3, info) + 010]);
  469.       break;
  470.  
  471.     case 'R':
  472.       (*info->fprintf_func)
  473.     (info->stream, "%s",
  474.      reg_names[fetch_arg (buffer, place, 4, info)]);
  475.       break;
  476.  
  477.     case 'r':
  478.       regno = fetch_arg (buffer, place, 4, info);
  479.       if (regno > 7)
  480.     (*info->fprintf_func) (info->stream, "%s@", reg_names[regno]);
  481.       else
  482.     (*info->fprintf_func) (info->stream, "@(%s)", reg_names[regno]);
  483.       break;
  484.  
  485.     case 'F':
  486.       (*info->fprintf_func)
  487.     (info->stream, "%%fp%d",
  488.      fetch_arg (buffer, place, 3, info));
  489.       break;
  490.  
  491.     case 'O':
  492.       val = fetch_arg (buffer, place, 6, info);
  493.       if (val & 0x20)
  494.     (*info->fprintf_func) (info->stream, "%s", reg_names [val & 7]);
  495.       else
  496.     (*info->fprintf_func) (info->stream, "%d", val);
  497.       break;
  498.  
  499.     case '+':
  500.       (*info->fprintf_func)
  501.     (info->stream, "%s@+",
  502.      reg_names[fetch_arg (buffer, place, 3, info) + 8]);
  503.       break;
  504.  
  505.     case '-':
  506.       (*info->fprintf_func)
  507.     (info->stream, "%s@-",
  508.      reg_names[fetch_arg (buffer, place, 3, info) + 8]);
  509.       break;
  510.  
  511.     case 'k':
  512.       if (place == 'k')
  513.     (*info->fprintf_func)
  514.       (info->stream, "{%s}",
  515.        reg_names[fetch_arg (buffer, place, 3, info)]);
  516.       else if (place == 'C')
  517.     {
  518.       val = fetch_arg (buffer, place, 7, info);
  519.       if ( val > 63 )        /* This is a signed constant. */
  520.         val -= 128;
  521.       (*info->fprintf_func) (info->stream, "{#%d}", val);
  522.     }
  523.       else
  524.     return -2;
  525.       break;
  526.  
  527.     case '#':
  528.     case '^':
  529.       p1 = buffer + (*d == '#' ? 2 : 4);
  530.       if (place == 's')
  531.     val = fetch_arg (buffer, place, 4, info);
  532.       else if (place == 'C')
  533.     val = fetch_arg (buffer, place, 7, info);
  534.       else if (place == '8')
  535.     val = fetch_arg (buffer, place, 3, info);
  536.       else if (place == '3')
  537.     val = fetch_arg (buffer, place, 8, info);
  538.       else if (place == 'b')
  539.     val = NEXTBYTE (p1);
  540.       else if (place == 'w' || place == 'W')
  541.     val = NEXTWORD (p1);
  542.       else if (place == 'l')
  543.     val = NEXTLONG (p1);
  544.       else
  545.     return -2;
  546.       (*info->fprintf_func) (info->stream, "#%d", val);
  547.       break;
  548.  
  549.     case 'B':
  550.       if (place == 'b')
  551.     val = NEXTBYTE (p);
  552.       else if (place == 'B')
  553.     val = COERCE_SIGNED_CHAR(buffer[1]);
  554.       else if (place == 'w' || place == 'W')
  555.     val = NEXTWORD (p);
  556.       else if (place == 'l' || place == 'L' || place == 'C')
  557.     val = NEXTLONG (p);
  558.       else if (place == 'g')
  559.     {
  560.       val = NEXTBYTE (buffer);
  561.       if (val == 0)
  562.         val = NEXTWORD (p);
  563.       else if (val == -1)
  564.         val = NEXTLONG (p);
  565.     }
  566.       else if (place == 'c')
  567.     {
  568.       if (buffer[1] & 0x40)        /* If bit six is one, long offset */
  569.         val = NEXTLONG (p);
  570.       else
  571.         val = NEXTWORD (p);
  572.     }
  573.       else
  574.     return -2;
  575.  
  576.       (*info->print_address_func) (addr + val, info);
  577.       break;
  578.  
  579.     case 'd':
  580.       val = NEXTWORD (p);
  581.       (*info->fprintf_func)
  582.     (info->stream, "%s@(%d)",
  583.      reg_names[fetch_arg (buffer, place, 3, info)], val);
  584.       break;
  585.  
  586.     case 's':
  587.       (*info->fprintf_func) (info->stream, "%s",
  588.                  fpcr_names[fetch_arg (buffer, place, 3, info)]);
  589.       break;
  590.  
  591.     case 'I':
  592.       /* Get coprocessor ID... */
  593.       val = fetch_arg (buffer, 'd', 3, info);
  594.       
  595.       if (val != 1)                /* Unusual coprocessor ID? */
  596.     (*info->fprintf_func) (info->stream, "(cpid=%d) ", val);
  597.       break;
  598.  
  599.     case '*':
  600.     case '~':
  601.     case '%':
  602.     case ';':
  603.     case '@':
  604.     case '!':
  605.     case '$':
  606.     case '?':
  607.     case '/':
  608.     case '&':
  609.     case '`':
  610.     case '|':
  611.  
  612.       if (place == 'd')
  613.     {
  614.       val = fetch_arg (buffer, 'x', 6, info);
  615.       val = ((val & 7) << 3) + ((val >> 3) & 7);
  616.     }
  617.       else
  618.     val = fetch_arg (buffer, 's', 6, info);
  619.  
  620.       /* Get register number assuming address register.  */
  621.       regno = (val & 7) + 8;
  622.       regname = reg_names[regno];
  623.       switch (val >> 3)
  624.     {
  625.     case 0:
  626.       (*info->fprintf_func) (info->stream, "%s", reg_names[val]);
  627.       break;
  628.  
  629.     case 1:
  630.       (*info->fprintf_func) (info->stream, "%s", regname);
  631.       break;
  632.  
  633.     case 2:
  634.       (*info->fprintf_func) (info->stream, "%s@", regname);
  635.       break;
  636.  
  637.     case 3:
  638.       (*info->fprintf_func) (info->stream, "%s@+", regname);
  639.       break;
  640.  
  641.     case 4:
  642.       (*info->fprintf_func) (info->stream, "%s@-", regname);
  643.       break;
  644.  
  645.     case 5:
  646.       val = NEXTWORD (p);
  647.       (*info->fprintf_func) (info->stream, "%s@(%d)", regname, val);
  648.       break;
  649.  
  650.     case 6:
  651.       p = print_indexed (regno, p, addr, info);
  652.       break;
  653.  
  654.     case 7:
  655.       switch (val & 7)
  656.         {
  657.         case 0:
  658.           val = NEXTWORD (p);
  659.           (*info->print_address_func) (val, info);
  660.           break;
  661.  
  662.         case 1:
  663.           val = NEXTLONG (p);
  664.           (*info->print_address_func) (val, info);
  665.           break;
  666.  
  667.         case 2:
  668.           val = NEXTWORD (p);
  669.           (*info->print_address_func) (addr + val, info);
  670.           break;
  671.  
  672.         case 3:
  673.           p = print_indexed (-1, p, addr, info);
  674.           break;
  675.  
  676.         case 4:
  677.           flt_p = 1;    /* Assume it's a float... */
  678.           switch( place )
  679.           {
  680.         case 'b':
  681.           val = NEXTBYTE (p);
  682.           flt_p = 0;
  683.           break;
  684.  
  685.         case 'w':
  686.           val = NEXTWORD (p);
  687.           flt_p = 0;
  688.           break;
  689.  
  690.         case 'l':
  691.           val = NEXTLONG (p);
  692.           flt_p = 0;
  693.           break;
  694.  
  695.         case 'f':
  696.           NEXTSINGLE(flval, p);
  697.           break;
  698.  
  699.         case 'F':
  700.           NEXTDOUBLE(flval, p);
  701.           break;
  702.  
  703.         case 'x':
  704.           FETCH_DATA (info, p + 12);
  705.           floatformat_to_double (&floatformat_m68881_ext,
  706.                      (char *) p, &flval);
  707.           p += 12;
  708.           break;
  709.  
  710.         case 'p':
  711.           flval = NEXTPACKED(p);
  712.           break;
  713.  
  714.         default:
  715.           return -1;
  716.           }
  717.           if ( flt_p )    /* Print a float? */
  718.         (*info->fprintf_func) (info->stream, "#%g", flval);
  719.           else
  720.         (*info->fprintf_func) (info->stream, "#%d", val);
  721.           break;
  722.  
  723.         default:
  724.           return -1;
  725.         }
  726.     }
  727.       break;
  728.  
  729.     case 'L':
  730.     case 'l':
  731.     if (place == 'w')
  732.       {
  733.         char doneany;
  734.         p1 = buffer + 2;
  735.         val = NEXTWORD (p1);
  736.         /* Move the pointer ahead if this point is farther ahead
  737.            than the last.  */
  738.         p = p1 > p ? p1 : p;
  739.         if (val == 0)
  740.           {
  741.         (*info->fprintf_func) (info->stream, "#0");
  742.         break;
  743.           }
  744.         if (*d == 'l')
  745.           {
  746.         register int newval = 0;
  747.         for (regno = 0; regno < 16; ++regno)
  748.           if (val & (0x8000 >> regno))
  749.             newval |= 1 << regno;
  750.         val = newval;
  751.           }
  752.         val &= 0xffff;
  753.         doneany = 0;
  754.         for (regno = 0; regno < 16; ++regno)
  755.           if (val & (1 << regno))
  756.         {
  757.           int first_regno;
  758.           if (doneany)
  759.             (*info->fprintf_func) (info->stream, "/");
  760.           doneany = 1;
  761.           (*info->fprintf_func) (info->stream, "%s", reg_names[regno]);
  762.           first_regno = regno;
  763.           while (val & (1 << (regno + 1)))
  764.             ++regno;
  765.           if (regno > first_regno)
  766.             (*info->fprintf_func) (info->stream, "-%s",
  767.                        reg_names[regno]);
  768.         }
  769.       }
  770.     else if (place == '3')
  771.       {
  772.         /* `fmovem' insn.  */
  773.         char doneany;
  774.         val = fetch_arg (buffer, place, 8, info);
  775.         if (val == 0)
  776.           {
  777.         (*info->fprintf_func) (info->stream, "#0");
  778.         break;
  779.           }
  780.         if (*d == 'l')
  781.           {
  782.         register int newval = 0;
  783.         for (regno = 0; regno < 8; ++regno)
  784.           if (val & (0x80 >> regno))
  785.             newval |= 1 << regno;
  786.         val = newval;
  787.           }
  788.         val &= 0xff;
  789.         doneany = 0;
  790.         for (regno = 0; regno < 8; ++regno)
  791.           if (val & (1 << regno))
  792.         {
  793.           int first_regno;
  794.           if (doneany)
  795.             (*info->fprintf_func) (info->stream, "/");
  796.           doneany = 1;
  797.           (*info->fprintf_func) (info->stream, "%%fp%d", regno);
  798.           first_regno = regno;
  799.           while (val & (1 << (regno + 1)))
  800.             ++regno;
  801.           if (regno > first_regno)
  802.             (*info->fprintf_func) (info->stream, "-%%fp%d", regno);
  803.         }
  804.       }
  805.     else if (place == '8')
  806.       {
  807.         /* fmoveml for FP status registers */
  808.         (*info->fprintf_func) (info->stream, "%s",
  809.                    fpcr_names[fetch_arg (buffer, place, 3,
  810.                              info)]);
  811.       }
  812.     else
  813.       return -2;
  814.       break;
  815.  
  816.     case 'X':
  817.       place = '8';
  818.     case 'Y':
  819.     case 'Z':
  820.     case 'W':
  821.     case '0':
  822.     case '1':
  823.     case '2':
  824.     case '3':
  825.       {
  826.     int val = fetch_arg (buffer, place, 5, info);
  827.     char *name = 0;
  828.     switch (val)
  829.       {
  830.       case 2: name = "%tt0"; break;
  831.       case 3: name = "%tt1"; break;
  832.       case 0x10: name = "%tc"; break;
  833.       case 0x11: name = "%drp"; break;
  834.       case 0x12: name = "%srp"; break;
  835.       case 0x13: name = "%crp"; break;
  836.       case 0x14: name = "%cal"; break;
  837.       case 0x15: name = "%val"; break;
  838.       case 0x16: name = "%scc"; break;
  839.       case 0x17: name = "%ac"; break;
  840.        case 0x18: name = "%psr"; break;
  841.       case 0x19: name = "%pcsr"; break;
  842.       case 0x1c:
  843.       case 0x1d:
  844.         {
  845.           int break_reg = ((buffer[3] >> 2) & 7);
  846.           (*info->fprintf_func)
  847.         (info->stream, val == 0x1c ? "%%bad%d" : "%%bac%d",
  848.          break_reg);
  849.         }
  850.         break;
  851.       default:
  852.         (*info->fprintf_func) (info->stream, "<mmu register %d>", val);
  853.       }
  854.     if (name)
  855.       (*info->fprintf_func) (info->stream, "%s", name);
  856.       }
  857.       break;
  858.  
  859.     case 'f':
  860.       {
  861.     int fc = fetch_arg (buffer, place, 5, info);
  862.     if (fc == 1)
  863.       (*info->fprintf_func) (info->stream, "%%dfc");
  864.     else if (fc == 0)
  865.       (*info->fprintf_func) (info->stream, "%%sfc");
  866.     else
  867.       (*info->fprintf_func) (info->stream, "<function code %d>", fc);
  868.       }
  869.       break;
  870.  
  871.     case 'V':
  872.       (*info->fprintf_func) (info->stream, "%%val");
  873.       break;
  874.  
  875.     case 't':
  876.       {
  877.     int level = fetch_arg (buffer, place, 3, info);
  878.     (*info->fprintf_func) (info->stream, "%d", level);
  879.       }
  880.       break;
  881.  
  882.     default:
  883.       return -2;
  884.     }
  885.  
  886.   return p - p0;
  887. }
  888.  
  889. /* Fetch BITS bits from a position in the instruction specified by CODE.
  890.    CODE is a "place to put an argument", or 'x' for a destination
  891.    that is a general address (mode and register).
  892.    BUFFER contains the instruction.  */
  893.  
  894. static int
  895. fetch_arg (buffer, code, bits, info)
  896.      unsigned char *buffer;
  897.      int code;
  898.      int bits;
  899.      disassemble_info *info;
  900. {
  901.   register int val = 0;
  902.   switch (code)
  903.     {
  904.     case 's':
  905.       val = buffer[1];
  906.       break;
  907.  
  908.     case 'd':            /* Destination, for register or quick.  */
  909.       val = (buffer[0] << 8) + buffer[1];
  910.       val >>= 9;
  911.       break;
  912.  
  913.     case 'x':            /* Destination, for general arg */
  914.       val = (buffer[0] << 8) + buffer[1];
  915.       val >>= 6;
  916.       break;
  917.  
  918.     case 'k':
  919.       FETCH_DATA (info, buffer + 3);
  920.       val = (buffer[3] >> 4);
  921.       break;
  922.  
  923.     case 'C':
  924.       FETCH_DATA (info, buffer + 3);
  925.       val = buffer[3];
  926.       break;
  927.  
  928.     case '1':
  929.       FETCH_DATA (info, buffer + 3);
  930.       val = (buffer[2] << 8) + buffer[3];
  931.       val >>= 12;
  932.       break;
  933.  
  934.     case '2':
  935.       FETCH_DATA (info, buffer + 3);
  936.       val = (buffer[2] << 8) + buffer[3];
  937.       val >>= 6;
  938.       break;
  939.  
  940.     case '3':
  941.     case 'j':
  942.       FETCH_DATA (info, buffer + 3);
  943.       val = (buffer[2] << 8) + buffer[3];
  944.       break;
  945.  
  946.     case '4':
  947.       FETCH_DATA (info, buffer + 5);
  948.       val = (buffer[4] << 8) + buffer[5];
  949.       val >>= 12;
  950.       break;
  951.  
  952.     case '5':
  953.       FETCH_DATA (info, buffer + 5);
  954.       val = (buffer[4] << 8) + buffer[5];
  955.       val >>= 6;
  956.       break;
  957.  
  958.     case '6':
  959.       FETCH_DATA (info, buffer + 5);
  960.       val = (buffer[4] << 8) + buffer[5];
  961.       break;
  962.  
  963.     case '7':
  964.       FETCH_DATA (info, buffer + 3);
  965.       val = (buffer[2] << 8) + buffer[3];
  966.       val >>= 7;
  967.       break;
  968.       
  969.     case '8':
  970.       FETCH_DATA (info, buffer + 3);
  971.       val = (buffer[2] << 8) + buffer[3];
  972.       val >>= 10;
  973.       break;
  974.  
  975.     case '9':
  976.       FETCH_DATA (info, buffer + 3);
  977.       val = (buffer[2] << 8) + buffer[3];
  978.       val >>= 5;
  979.       break;
  980.  
  981.     case 'e':
  982.       val = (buffer[1] >> 6);
  983.       break;
  984.  
  985.     default:
  986.       abort ();
  987.     }
  988.  
  989.   switch (bits)
  990.     {
  991.     case 2:
  992.       return val & 3;
  993.     case 3:
  994.       return val & 7;
  995.     case 4:
  996.       return val & 017;
  997.     case 5:
  998.       return val & 037;
  999.     case 6:
  1000.       return val & 077;
  1001.     case 7:
  1002.       return val & 0177;
  1003.     case 8:
  1004.       return val & 0377;
  1005.     case 12:
  1006.       return val & 07777;
  1007.     default:
  1008.       abort ();
  1009.     }
  1010. }
  1011.  
  1012. /* Print an indexed argument.  The base register is BASEREG (-1 for pc).
  1013.    P points to extension word, in buffer.
  1014.    ADDR is the nominal core address of that extension word.  */
  1015.  
  1016. static unsigned char *
  1017. print_indexed (basereg, p, addr, info)
  1018.      int basereg;
  1019.      unsigned char *p;
  1020.      bfd_vma addr;
  1021.      disassemble_info *info;
  1022. {
  1023.   register int word;
  1024.   static char *const scales[] = {"", ":2", ":4", ":8"};
  1025.   bfd_vma base_disp;
  1026.   bfd_vma outer_disp;
  1027.   char buf[40];
  1028.   char vmabuf[50];
  1029.  
  1030.   word = NEXTWORD (p);
  1031.  
  1032.   /* Generate the text for the index register.
  1033.      Where this will be output is not yet determined.  */
  1034.   sprintf (buf, "%s:%c%s",
  1035.        reg_names[(word >> 12) & 0xf],
  1036.        (word & 0x800) ? 'l' : 'w',
  1037.        scales[(word >> 9) & 3]);
  1038.  
  1039.   /* Handle the 68000 style of indexing.  */
  1040.  
  1041.   if ((word & 0x100) == 0)
  1042.     {
  1043.       word &= 0xff;
  1044.       if ((word & 0x80) != 0)
  1045.     word -= 0x100;
  1046.       if (basereg == -1)
  1047.     word += addr;
  1048.       print_base (basereg, word, info);
  1049.       (*info->fprintf_func) (info->stream, ",%s)", buf);
  1050.       return p;
  1051.     }
  1052.  
  1053.   /* Handle the generalized kind.  */
  1054.   /* First, compute the displacement to add to the base register.  */
  1055.  
  1056.   if (word & 0200)
  1057.     {
  1058.       if (basereg == -1)
  1059.     basereg = -3;
  1060.       else
  1061.     basereg = -2;
  1062.     }
  1063.   if (word & 0100)
  1064.     buf[0] = '\0';
  1065.   base_disp = 0;
  1066.   switch ((word >> 4) & 3)
  1067.     {
  1068.     case 2:
  1069.       base_disp = NEXTWORD (p);
  1070.       break;
  1071.     case 3:
  1072.       base_disp = NEXTLONG (p);
  1073.     }
  1074.   if (basereg == -1)
  1075.     base_disp += addr;
  1076.  
  1077.   /* Handle single-level case (not indirect) */
  1078.  
  1079.   if ((word & 7) == 0)
  1080.     {
  1081.       print_base (basereg, base_disp, info);
  1082.       if (buf[0] != '\0')
  1083.     (*info->fprintf_func) (info->stream, ",%s", buf);
  1084.       (*info->fprintf_func) (info->stream, ")");
  1085.       return p;
  1086.     }
  1087.  
  1088.   /* Two level.  Compute displacement to add after indirection.  */
  1089.  
  1090.   outer_disp = 0;
  1091.   switch (word & 3)
  1092.     {
  1093.     case 2:
  1094.       outer_disp = NEXTWORD (p);
  1095.       break;
  1096.     case 3:
  1097.       outer_disp = NEXTLONG (p);
  1098.     }
  1099.  
  1100.   print_base (basereg, base_disp, info);
  1101.   if ((word & 4) == 0 && buf[0] != '\0')
  1102.     {
  1103.       (*info->fprintf_func) (info->stream, ",%s", buf);
  1104.       buf[0] = '\0';
  1105.     }
  1106.   sprintf_vma (vmabuf, outer_disp);
  1107.   (*info->fprintf_func) (info->stream, ")@(%s", vmabuf);
  1108.   if (buf[0] != '\0')
  1109.     (*info->fprintf_func) (info->stream, ",%s", buf);
  1110.   (*info->fprintf_func) (info->stream, ")");
  1111.  
  1112.   return p;
  1113. }
  1114.  
  1115. /* Print a base register REGNO and displacement DISP, on INFO->STREAM.
  1116.    REGNO = -1 for pc, -2 for none (suppressed).  */
  1117.  
  1118. static void
  1119. print_base (regno, disp, info)
  1120.      int regno;
  1121.      bfd_vma disp;
  1122.      disassemble_info *info;
  1123. {
  1124.   if (regno == -1)
  1125.     {
  1126.       (*info->fprintf_func) (info->stream, "%%pc@(");
  1127.       (*info->print_address_func) (disp, info);
  1128.     }
  1129.   else
  1130.     {
  1131.       char buf[50];
  1132.  
  1133.       if (regno == -2)
  1134.     (*info->fprintf_func) (info->stream, "@(");
  1135.       else if (regno == -3)
  1136.     (*info->fprintf_func) (info->stream, "%%zpc@(");
  1137.       else
  1138.     (*info->fprintf_func) (info->stream, "%s@(", reg_names[regno]);
  1139.  
  1140.       sprintf_vma (buf, disp);
  1141.       (*info->fprintf_func) (info->stream, "%s", buf);
  1142.     }
  1143. }
  1144.