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 / h8500-dis.c < prev    next >
C/C++ Source or Header  |  1996-09-28  |  8KB  |  345 lines

  1. /* Disassemble h8500 instructions.
  2.    Copyright (C) 1993 Free Software Foundation, Inc.
  3.  
  4. This program 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 <stdio.h>
  19.  
  20. #define DISASSEMBLER_TABLE
  21. #define DEFINE_TABLE
  22.  
  23. #include "h8500-opc.h"
  24. #include "dis-asm.h"
  25.  
  26. /* Maximum length of an instruction.  */
  27. #define MAXLEN 8
  28.  
  29. #include <setjmp.h>
  30.  
  31. struct private
  32. {
  33.   /* Points to first byte not fetched.  */
  34.   bfd_byte *max_fetched;
  35.   bfd_byte the_buffer[MAXLEN];
  36.   bfd_vma insn_start;
  37.   jmp_buf bailout;
  38. };
  39.  
  40. /* Make sure that bytes from INFO->PRIVATE_DATA->BUFFER (inclusive)
  41.    to ADDR (exclusive) are valid.  Returns 1 for success, longjmps
  42.    on error.  */
  43. #define FETCH_DATA(info, addr) \
  44.   ((addr) <= ((struct private *)(info->private_data))->max_fetched \
  45.    ? 1 : fetch_data ((info), (addr)))
  46.  
  47. static int
  48. fetch_data (info, addr)
  49.      struct disassemble_info *info;
  50.      bfd_byte *addr;
  51. {
  52.   int status;
  53.   struct private *priv = (struct private *) info->private_data;
  54.   bfd_vma start = priv->insn_start + (priv->max_fetched - priv->the_buffer);
  55.  
  56.   status = (*info->read_memory_func) (start,
  57.                       priv->max_fetched,
  58.                       addr - priv->max_fetched,
  59.                       info);
  60.   if (status != 0)
  61.     {
  62.       (*info->memory_error_func) (status, start, info);
  63.       longjmp (priv->bailout, 1);
  64.     }
  65.   else
  66.     priv->max_fetched = addr;
  67.   return 1;
  68. }
  69.  
  70. static char *crname[] =
  71. {"sr", "ccr", "*", "br", "ep", "dp", "*", "tp"};
  72.  
  73. int
  74. print_insn_h8500 (addr, info)
  75.      bfd_vma addr;
  76.      disassemble_info *info;
  77. {
  78.   h8500_opcode_info *opcode;
  79.   void *stream = info->stream;
  80.   fprintf_ftype func = info->fprintf_func;
  81.  
  82.   struct private priv;
  83.   bfd_byte *buffer = priv.the_buffer;
  84.  
  85.   info->private_data = (PTR) & priv;
  86.   priv.max_fetched = priv.the_buffer;
  87.   priv.insn_start = addr;
  88.   if (setjmp (priv.bailout) != 0)
  89.     /* Error return.  */
  90.     return -1;
  91.  
  92. if (0)  {
  93.     static    int one;
  94.     if (!one ) 
  95.       {
  96.     one = 1;
  97.     for (opcode = h8500_table; opcode->name; opcode++)
  98.       {
  99.         if ((opcode->bytes[0].contents & 0x8) == 0)
  100.           printf("%s\n", opcode->name);
  101.       }
  102.       }
  103.   }
  104.  
  105.  
  106.   /* Run down the table to find the one which matches */
  107.   for (opcode = h8500_table; opcode->name; opcode++)
  108.     {
  109.       int byte;
  110.       int rn;
  111.       int rd;
  112.       int rs;
  113.       int disp;
  114.       int abs;
  115.       int imm;
  116.       int pcrel;
  117.       int qim;
  118.       int i;
  119.       int cr;
  120.       for (byte = 0; byte < opcode->length; byte++)
  121.     {
  122.       FETCH_DATA (info, buffer + byte + 1);
  123.       if ((buffer[byte] & opcode->bytes[byte].mask)
  124.           != (opcode->bytes[byte].contents))
  125.         {
  126.           goto next;
  127.         }
  128.       else
  129.         {
  130.           /* extract any info parts */
  131.           switch (opcode->bytes[byte].insert)
  132.         {
  133.         case 0:
  134.         case FP:
  135.           break;
  136.         default:
  137.           func (stream, "can't cope with insert %d\n",
  138.             opcode->bytes[byte].insert);
  139.           break;
  140.         case RN:
  141.           rn = buffer[byte] & 0x7;
  142.           break;
  143.         case RS:
  144.           rs = buffer[byte] & 0x7;
  145.           break;
  146.         case CRB:
  147.           cr = buffer[byte] & 0x7;
  148.           if (cr == 0)
  149.             goto next;
  150.           break;
  151.         case CRW:
  152.           cr = buffer[byte] & 0x7;
  153.           if (cr != 0)
  154.             goto next;
  155.           break;
  156.         case DISP16:
  157.           FETCH_DATA (info, buffer + byte + 2);
  158.           disp = (buffer[byte] << 8) | (buffer[byte + 1]);
  159.           break;
  160.         case FPIND_D8:
  161.         case DISP8:
  162.           disp = ((char) (buffer[byte]));
  163.           break;
  164.         case RD:
  165.         case RDIND:
  166.           rd = buffer[byte] & 0x7;
  167.           break;
  168.         case ABS24:
  169.           FETCH_DATA (info, buffer + byte + 3);
  170.           abs =
  171.             (buffer[byte] << 16)
  172.             | (buffer[byte + 1] << 8)
  173.             | (buffer[byte + 2]);
  174.           break;
  175.         case ABS16:
  176.           FETCH_DATA (info, buffer + byte + 2);
  177.           abs = (buffer[byte] << 8) | (buffer[byte + 1]);
  178.           break;
  179.         case ABS8:
  180.           abs = (buffer[byte]);
  181.           break;
  182.         case IMM16:
  183.           FETCH_DATA (info, buffer + byte + 2);
  184.           imm = (buffer[byte] << 8) | (buffer[byte + 1]);
  185.           break;
  186.         case IMM4:
  187.           imm = (buffer[byte]) & 0xf;
  188.           break;
  189.         case IMM8:
  190.         case RLIST:
  191.           imm = (buffer[byte]);
  192.           break;
  193.         case PCREL16:
  194.           FETCH_DATA (info, buffer + byte + 2);
  195.           pcrel = (buffer[byte] << 8) | (buffer[byte + 1]);
  196.           break;
  197.         case PCREL8:
  198.           pcrel = (buffer[byte]);
  199.           break;
  200.         case QIM:
  201.           switch (buffer[byte] & 0x7)
  202.             {
  203.             case 0:
  204.               qim = 1;
  205.               break;
  206.             case 1:
  207.               qim = 2;
  208.               break;
  209.             case 4:
  210.               qim = -1;
  211.               break;
  212.             case 5:
  213.               qim = -2;
  214.               break;
  215.             }
  216.           break;
  217.  
  218.         }
  219.         }
  220.     }
  221.       /* We get here when all the masks have passed so we can output the
  222.      operands*/
  223.       FETCH_DATA (info, buffer + opcode->length);
  224.       for (i = 0; i < opcode->length; i++)
  225.     {
  226.       (func) (stream, "%02x ", buffer[i]);
  227.     }
  228.       for (; i < 6; i++)
  229.     {
  230.       (func) (stream, "   ");
  231.     }
  232.       (func) (stream, "%s\t", opcode->name);
  233.       for (i = 0; i < opcode->nargs; i++)
  234.     {
  235.       if (i)
  236.         (func) (stream, ",");
  237.       switch (opcode->arg_type[i])
  238.         {
  239.         case FP:
  240.           func (stream, "fp");
  241.           break;
  242.         case RNIND_D16:
  243.           func (stream, "@(0x%x:16,r%d)", disp, rn);
  244.           break;
  245.         case RNIND_D8:
  246.           func (stream, "@(0x%x:8 (%d),r%d)", disp & 0xff, disp, rn);
  247.           break;
  248.         case RDIND_D16:
  249.           func (stream, "@(0x%x:16,r%d)", disp, rd);
  250.           break;
  251.         case RDIND_D8:
  252.           func (stream, "@(0x%x:8 (%d), r%d)", disp & 0xff, disp, rd);
  253.           break;
  254.         case FPIND_D8:
  255.           func (stream, "@(0x%x:8 (%d), fp)", disp & 0xff, disp, rn);
  256.           break;
  257.         case CRB:
  258.         case CRW:
  259.           func (stream, "%s", crname[cr]);
  260.           break;
  261.         case RN:
  262.           func (stream, "r%d", rn);
  263.           break;
  264.         case RD:
  265.           func (stream, "r%d", rd);
  266.           break;
  267.         case RS:
  268.           func (stream, "r%d", rs);
  269.           break;
  270.         case RNDEC:
  271.           func (stream, "@-r%d", rn);
  272.           break;
  273.         case RNINC:
  274.           func (stream, "@r%d+", rn);
  275.           break;
  276.         case RNIND:
  277.           func (stream, "@r%d", rn);
  278.           break;
  279.         case RDIND:
  280.           func (stream, "@r%d", rd);
  281.           break;
  282.         case SPINC:
  283.           func (stream, "@sp+");
  284.           break;
  285.         case SPDEC:
  286.           func (stream, "@-sp");
  287.           break;
  288.         case ABS24:
  289.           func (stream, "@0x%0x:24", abs);
  290.           break;
  291.         case ABS16:
  292.           func (stream, "@0x%0x:16", abs & 0xffff);
  293.           break;
  294.         case ABS8:
  295.           func (stream, "@0x%0x:8", abs & 0xff);
  296.           break;
  297.         case IMM16:
  298.           func (stream, "#0x%0x:16", imm & 0xffff);
  299.           break;
  300.         case RLIST:
  301.           {
  302.         int i;
  303.         int nc = 0;
  304.         func (stream, "(");
  305.         for (i = 0; i < 8; i++)
  306.           {
  307.             if (imm & (1 << i))
  308.               {
  309.             func (stream, "r%d", i);
  310.             if (nc)
  311.               func (stream, ",");
  312.             nc = 1;
  313.               }
  314.           }
  315.         func (stream, ")");
  316.           }
  317.           break;
  318.         case IMM8:
  319.           func (stream, "#0x%0x:8", imm & 0xff);
  320.           break;
  321.         case PCREL16:
  322.           func (stream, "0x%0x:16", (pcrel + addr + opcode->length) & 0xffff);
  323.           break;
  324.         case PCREL8:
  325.           func (stream, "#0x%0x:8",
  326.             ((char) pcrel + addr + opcode->length) & 0xffff);
  327.           break;
  328.         case QIM:
  329.           func (stream, "#%d:q", qim);
  330.           break;
  331.         case IMM4:
  332.           func (stream, "#%d:4", imm);
  333.           break;
  334.         }
  335.     }
  336.       return opcode->length;
  337.     next:;
  338.     }
  339.  
  340.   /* Couldn't understand anything */
  341.   func (stream, "%02x\t\t*unknown*", buffer[0]);
  342.   return 1;
  343.  
  344. }
  345.