home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Source Code 1993 July / THE_SOURCE_CODE_CD_ROM.iso / bsd_srcs / usr.bin / gdb / config / tahoe-pinsn.c < prev    next >
Encoding:
C/C++ Source or Header  |  1991-05-08  |  6.7 KB  |  260 lines

  1. /*-
  2.  * Copyright (c) 1991 The Regents of the University of California.
  3.  * All rights reserved.
  4.  *
  5.  * This code is derived from software contributed to Berkeley by the
  6.  * Distributed Computer Systems Lab, Department of Computer Science
  7.  * at the State University of New York at Buffalo.
  8.  *
  9.  * Redistribution and use in source and binary forms, with or without
  10.  * modification, are permitted provided that the following conditions
  11.  * are met:
  12.  * 1. Redistributions of source code must retain the above copyright
  13.  *    notice, this list of conditions and the following disclaimer.
  14.  * 2. Redistributions in binary form must reproduce the above copyright
  15.  *    notice, this list of conditions and the following disclaimer in the
  16.  *    documentation and/or other materials provided with the distribution.
  17.  * 3. All advertising materials mentioning features or use of this software
  18.  *    must display the following acknowledgement:
  19.  *    This product includes software developed by the University of
  20.  *    California, Berkeley and its contributors.
  21.  * 4. Neither the name of the University nor the names of its contributors
  22.  *    may be used to endorse or promote products derived from this software
  23.  *    without specific prior written permission.
  24.  *
  25.  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
  26.  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  27.  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  28.  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
  29.  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  30.  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  31.  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  32.  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  33.  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  34.  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  35.  * SUCH DAMAGE.
  36.  */
  37.  
  38. #ifndef lint
  39. static char sccsid[] = "@(#)tahoe-pinsn.c    6.3 (Berkeley) 5/8/91";
  40. #endif /* not lint */
  41.  
  42. #include <stdio.h>
  43.  
  44. #include "defs.h"
  45. #include "param.h"
  46. #include "symtab.h"
  47. #include "tahoe-opcode.h"
  48.  
  49. /* Tahoe instructions are never longer than this.  */
  50. #define MAXLEN 62
  51.  
  52. /* Number of elements in the opcode table.  */
  53. #define NOPCODES (sizeof votstrs / sizeof votstrs[0])
  54.  
  55. extern char *reg_names[];
  56.  
  57. static unsigned char *print_insn_arg ();
  58.  
  59. /* Print the Tahoe instruction at address MEMADDR in debugged memory,
  60.    on STREAM.  Returns length of the instruction, in bytes.  */
  61.  
  62. int
  63. print_insn (memaddr, stream)
  64.      CORE_ADDR memaddr;
  65.      FILE *stream;
  66. {
  67.   unsigned char buffer[MAXLEN];
  68.   register int i;
  69.   register unsigned char *p;
  70.   register char *d;
  71.  
  72.   read_memory (memaddr, buffer, MAXLEN);
  73.  
  74.   for (i = 0; i < NOPCODES; i++)
  75.     if (votstrs[i].detail.code == buffer[0]
  76.     || votstrs[i].detail.code == *(unsigned short *)buffer)
  77.       break;
  78.  
  79.   /* Handle undefined instructions.  */
  80.   if (i == NOPCODES)
  81.     {
  82.       fprintf (stream, "0%o", buffer[0]);
  83.       return 1;
  84.     }
  85.  
  86.   fprintf (stream, "%s", votstrs[i].name);
  87.  
  88.   /* Point at first byte of argument data,
  89.      and at descriptor for first argument.  */
  90.   p = buffer + 1 + (votstrs[i].detail.code >= 0x100);
  91.   d = votstrs[i].detail.args;
  92.  
  93.   if (*d)
  94.     fputc ('\t', stream);
  95.  
  96.   while (*d)
  97.     {
  98.       p = print_insn_arg (d, p, memaddr + (p - buffer), stream);
  99.       d += 2;
  100.       if (*d)
  101.     fprintf (stream, ",");
  102.     }
  103.   return p - buffer;
  104. }
  105. /*******************************************************************/
  106. static unsigned char *
  107. print_insn_arg (d, p, addr, stream)
  108.      char *d;
  109.      register char *p;
  110.      CORE_ADDR addr;
  111.      FILE *stream;
  112. {
  113.   int temp1 = 0;
  114.   register int regnum = *p & 0xf;
  115.   float floatlitbuf;
  116.  
  117.   if (*d == 'b')
  118.     {
  119.       if (d[1] == 'b')
  120.     fprintf (stream, "0x%x", addr + *p++ + 1);
  121.       else
  122.     {
  123.  
  124.       temp1 = *p;
  125.       temp1 <<= 8;
  126.       temp1 |= *(p + 1);
  127.       fprintf (stream, "0x%x", addr + temp1 + 2);
  128.       p += 2;
  129.     }
  130.     }
  131.   else
  132.     switch ((*p++ >> 4) & 0xf)
  133.       {
  134.       case 0:
  135.       case 1:
  136.       case 2:
  137.       case 3:            /* Liter>al(short immediate byte) mode */
  138.     if (d[1] == 'd' || d[1] == 'f' || d[1] == 'g' || d[1] == 'h')
  139.       {
  140.         *(int *)&floatlitbuf = 0x4000 + ((p[-1] & 0x3f) << 4);
  141.         fprintf (stream, "$%f", floatlitbuf);
  142.       }
  143.     else
  144.       fprintf (stream, "$%d", p[-1] & 0x3f);
  145.     break;
  146.  
  147.       case 4:            /* Indexed */
  148.     p = (char *) print_insn_arg (d, p, addr + 1, stream);
  149.     fprintf (stream, "[%s]", reg_names[regnum]);
  150.     break;
  151.  
  152.       case 5:            /* Register */
  153.     fprintf (stream, reg_names[regnum]);
  154.     break;
  155.  
  156.       case 7:            /* Autodecrement */
  157.     fputc ('-', stream);
  158.       case 6:            /* Register deferred */
  159.     fprintf (stream, "(%s)", reg_names[regnum]);
  160.     break;
  161.  
  162.       case 9:                    /* Absolute Address & Autoincrement deferred */
  163.     fputc ('*', stream);
  164.     if (regnum == PC_REGNUM)
  165.       {
  166.         temp1 = *p;
  167.         temp1 <<= 8;
  168.         temp1 |= *(p +1);
  169.  
  170.         fputc ('$', stream);
  171.         print_address (temp1, stream);
  172.         p += 4;
  173.         break;
  174.       }
  175.       case 8:            /*Immediate & Autoincrement SP */
  176.         if (regnum == 8)         /*88 is Immediate Byte Mode*/
  177.       fprintf (stream, "$%d", *p++);
  178.  
  179.     else if (regnum == 9)        /*89 is Immediate Word Mode*/
  180.       {
  181.         temp1 = *p;
  182.         temp1 <<= 8; 
  183.         temp1 |= *(p +1);
  184.         fprintf (stream, "$%d", temp1);
  185.         p += 2;
  186.       }  
  187.  
  188.     else if (regnum == PC_REGNUM)    /*8F is Immediate Long Mode*/
  189.       {
  190.         temp1 = *p;
  191.         temp1 <<=8;
  192.         temp1 |= *(p +1);
  193.         temp1 <<=8;
  194.         temp1 |= *(p +2);
  195.         temp1 <<= 8;
  196.         temp1 |= *(p +3);
  197.         fprintf (stream, "$%d", temp1);
  198.         p += 4;
  199.       }
  200.  
  201.     else                            /*8E is Autoincrement SP Mode*/
  202.           fprintf (stream, "(%s)+", reg_names[regnum]);
  203.     break;
  204.  
  205.       case 11:            /* Register + Byte Displacement Deferred Mode*/
  206.     fputc ('*', stream);
  207.       case 10:            /* Register + Byte Displacement Mode*/
  208.     if (regnum == PC_REGNUM)
  209.       print_address (addr + *p + 2, stream);
  210.     else
  211.       fprintf (stream, "%d(%s)", *p, reg_names[regnum]);
  212.     p += 1;
  213.     break;
  214.  
  215.       case 13:            /* Register + Word Displacement Deferred Mode*/
  216.     fputc ('*', stream);
  217.       case 12:            /* Register + Word Displacement Mode*/
  218.     temp1 = *p;
  219.     temp1 <<= 8;
  220.     temp1 |= *(p +1);
  221.     if (regnum == PC_REGNUM)
  222.       print_address (addr + temp1 + 3, stream);
  223.     else
  224.       fprintf (stream, "%d(%s)", temp1, reg_names[regnum]);
  225.     p += 2;
  226.     break;
  227.  
  228.       case 15:            /* Register + Long Displacement Deferred Mode*/
  229.     fputc ('*', stream);
  230.       case 14:            /* Register + Long Displacement Mode*/
  231.     temp1 = *p;
  232.     temp1 <<= 8;
  233.     temp1 |= *(p +1);
  234.     temp1 <<= 8;
  235.     temp1 |= *(p +2);
  236.     temp1 <<= 8;
  237.     temp1 |= *(p +3);
  238.     if (regnum == PC_REGNUM)
  239.       print_address (addr + temp1 + 5, stream);
  240.     else
  241.       fprintf (stream, "%d(%s)", temp1, reg_names[regnum]);
  242.     p += 4;
  243.       }
  244.  
  245.   return (unsigned char *) p;
  246. }
  247.  
  248.  
  249.  
  250.  
  251.  
  252.  
  253.  
  254.  
  255.  
  256.  
  257.  
  258.  
  259.  
  260.