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

  1. /* Disassemble SH instructions.
  2.    Copyright (C) 1993, 1995 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. #define STATIC_TABLE
  20. #define DEFINE_TABLE
  21.  
  22. #include "sh-opc.h"
  23. #include "dis-asm.h"
  24.  
  25. #define LITTLE_BIT 2
  26.  
  27. static int 
  28. print_insn_shx(memaddr, info)
  29.      bfd_vma memaddr;
  30.      struct disassemble_info *info;
  31. {
  32.   fprintf_ftype fprintf = info->fprintf_func;
  33.   void *stream = info->stream;
  34.   unsigned  char insn[2];
  35.   unsigned  char nibs[4];
  36.   int status;
  37.   int relmask = ~0;
  38.   sh_opcode_info *op;
  39.   
  40.   status = info->read_memory_func(memaddr, insn, 2, info);
  41.  
  42.   if (status != 0) 
  43.     {
  44.       info->memory_error_func(status, memaddr, info);
  45.       return -1;
  46.     }
  47.  
  48.  
  49.  
  50.   if (info->flags & LITTLE_BIT) 
  51.     {
  52.       nibs[0] = (insn[1] >> 4) & 0xf;
  53.       nibs[1] = insn[1] & 0xf;
  54.  
  55.       nibs[2] = (insn[0] >> 4) & 0xf;
  56.       nibs[3] = insn[0] & 0xf;
  57.     }
  58.   else 
  59.     {
  60.       nibs[0] = (insn[0] >> 4) & 0xf;
  61.       nibs[1] = insn[0] & 0xf;
  62.  
  63.       nibs[2] = (insn[1] >> 4) & 0xf;
  64.       nibs[3] = insn[1] & 0xf;
  65.     }
  66.  
  67.   for (op = sh_table; op->name; op++) 
  68.     {
  69.       int n;
  70.       int imm;
  71.       int rn;
  72.       int rm;
  73.       int rb;
  74.  
  75.       for (n = 0; n < 4; n++) {
  76.     int i = op->nibbles[n];
  77.     if (i < 16) 
  78.       {
  79.         if (nibs[n] == i) continue;
  80.         goto fail;
  81.       }
  82.     switch (i)
  83.       {
  84.       case BRANCH_8:
  85.         imm = (nibs[2] << 4) | (nibs[3]);      
  86.         if (imm & 0x80)
  87.           imm |= ~0xff;
  88.         imm = ((char)imm) * 2 + 4 ;
  89.         goto ok;
  90.  
  91.       case BRANCH_12:
  92.         imm = ((nibs[1]) << 8) | (nibs[2] << 4) | (nibs[3]);
  93.         if (imm & 0x800)
  94.           imm |= ~0xfff;
  95.         imm = imm * 2 + 4;
  96.         goto ok;
  97.       case IMM_4:
  98.         imm = nibs[3];
  99.         goto ok;
  100.       case IMM_4BY2:
  101.         imm = nibs[3] <<1;
  102.         goto ok;
  103.       case IMM_4BY4:
  104.         imm = nibs[3] <<2;
  105.         goto ok;
  106.  
  107.         
  108.       case IMM_8:
  109.         imm = (nibs[2] << 4) | nibs[3];
  110.         goto ok;
  111.       case PCRELIMM_8BY2:
  112.         imm = ((nibs[2] << 4) | nibs[3]) <<1;
  113.         relmask  = ~1;
  114.         
  115.         goto ok;
  116.  
  117.       case PCRELIMM_8BY4:
  118.         imm = ((nibs[2] << 4) | nibs[3]) <<2;
  119.         relmask  = ~3;        
  120.         goto ok;
  121.         
  122.       case IMM_8BY2:
  123.         imm = ((nibs[2] << 4) | nibs[3]) <<1;
  124.         goto ok;
  125.       case IMM_8BY4:
  126.         imm = ((nibs[2] << 4) | nibs[3]) <<2;
  127.         goto ok;
  128.       case DISP_8:
  129.         imm = (nibs[2] << 4) | (nibs[3]);      
  130.         goto ok;
  131.       case DISP_4:
  132.         imm = nibs[3];
  133.         goto ok;
  134.       case REG_N:
  135.         rn = nibs[n];
  136.         break;
  137.       case REG_M:
  138.         rm = nibs[n];
  139.         break;
  140.           case REG_B:
  141.             rb = nibs[n] & 0x07;
  142.             break;    
  143.       default:
  144.         abort();
  145.       }
  146.  
  147.       }
  148.     ok:
  149.       fprintf(stream,"%s\t", op->name);
  150.       for (n = 0; n < 3 && op->arg[n] != A_END; n++) 
  151.     {
  152.       if (n && op->arg[1] != A_END)
  153.         fprintf(stream,",");
  154.       switch (op->arg[n]) 
  155.         {
  156.         case A_IMM:
  157.           fprintf(stream,"#%d", (char)(imm));
  158.           break;
  159.         case A_R0:
  160.           fprintf(stream,"r0");
  161.           break;
  162.         case A_REG_N:
  163.           fprintf(stream,"r%d", rn);
  164.           break;
  165.         case A_INC_N:
  166.           fprintf(stream,"@r%d+", rn);    
  167.           break;
  168.         case A_DEC_N:
  169.           fprintf(stream,"@-r%d", rn);    
  170.           break;
  171.         case A_IND_N:
  172.           fprintf(stream,"@r%d", rn);    
  173.           break;
  174.         case A_DISP_REG_N:
  175.           fprintf(stream,"@(%d,r%d)",imm, rn);    
  176.           break;
  177.         case A_REG_M:
  178.           fprintf(stream,"r%d", rm);
  179.           break;
  180.         case A_INC_M:
  181.           fprintf(stream,"@r%d+", rm);    
  182.           break;
  183.         case A_DEC_M:
  184.           fprintf(stream,"@-r%d", rm);    
  185.           break;
  186.         case A_IND_M:
  187.           fprintf(stream,"@r%d", rm);    
  188.           break;
  189.         case A_DISP_REG_M:
  190.           fprintf(stream,"@(%d,r%d)",imm, rm);    
  191.           break;
  192.             case A_REG_B:
  193.               fprintf(stream,"r%d_bank", rb);
  194.           break;
  195.         case A_DISP_PC:
  196.           fprintf(stream,"0x%0x", imm+ 4+(memaddr&relmask));
  197.           break;
  198.         case A_IND_R0_REG_N:
  199.           fprintf(stream,"@(r0,r%d)", rn);
  200.           break; 
  201.         case A_IND_R0_REG_M:
  202.           fprintf(stream,"@(r0,r%d)", rm);
  203.           break; 
  204.         case A_DISP_GBR:
  205.           fprintf(stream,"@(%d,gbr)",imm);
  206.           break;
  207.         case A_R0_GBR:
  208.           fprintf(stream,"@(r0,gbr)");
  209.           break;
  210.         case A_BDISP12:
  211.         case A_BDISP8:
  212.           (*info->print_address_func) (imm + memaddr, info);
  213.           break;
  214.         case A_SR:
  215.           fprintf(stream,"sr");
  216.           break;
  217.         case A_GBR:
  218.           fprintf(stream,"gbr");
  219.           break;
  220.         case A_VBR:
  221.           fprintf(stream,"vbr");
  222.           break;
  223.         case A_SSR:
  224.           fprintf(stream,"ssr");
  225.           break;
  226.         case A_SPC:
  227.           fprintf(stream,"spc");
  228.           break;
  229.         case A_MACH:
  230.           fprintf(stream,"mach");
  231.           break;
  232.         case A_MACL:
  233.           fprintf(stream,"macl");
  234.           break;
  235.         case A_PR:
  236.           fprintf(stream,"pr");
  237.           break;
  238.         case F_REG_N:
  239.           fprintf(stream,"fr%d", rn);
  240.           break;
  241.         case F_REG_M:
  242.           fprintf(stream,"fr%d", rm);
  243.           break;
  244.         case FPSCR_M:
  245.         case FPSCR_N:
  246.           fprintf(stream,"fpscr");
  247.           break;
  248.         case FPUL_M:
  249.         case FPUL_N:
  250.           fprintf(stream,"fpul");
  251.           break;
  252.         case F_FR0:
  253.           fprintf(stream,"fr0");
  254.           break;
  255.         default:
  256.           abort();
  257.         }
  258.     
  259.     }
  260.       if (!(info->flags & 1)
  261.       && (op->name[0] == 'j'
  262.           || (op->name[0] == 'b'
  263.           && (op->name[1] == 'r' 
  264.               || op->name[1] == 's'))
  265.           || (op->name[0] == 'r' && op->name[1] == 't')
  266.           || (op->name[0] == 'b' && op->name[2] == '.')))
  267.     {
  268.       info->flags |= 1;
  269.       fprintf(stream,"\t(slot ");  print_insn_shx(memaddr +2, info);
  270.       info->flags &= ~1;
  271.       fprintf(stream,")");
  272.       return 4;
  273.     }
  274.       
  275.       return 2;
  276.     fail:
  277.       ;
  278.  
  279.     }
  280.   fprintf(stream,".word 0x%x%x%x%x", nibs[0], nibs[1], nibs[2], nibs[3]);
  281.   return 2;
  282. }
  283.  
  284.  
  285. int 
  286. print_insn_shl(memaddr, info)
  287.      bfd_vma memaddr;
  288.      struct disassemble_info *info;
  289. {
  290.   int r;
  291.   info->flags = LITTLE_BIT;
  292.   r =print_insn_shx (memaddr, info);
  293.   return r;
  294. }
  295.  
  296. int 
  297. print_insn_sh(memaddr, info)
  298.      bfd_vma memaddr;
  299.      struct disassemble_info *info;
  300. {
  301.   int r;
  302.   info->flags = 0;
  303.   r =print_insn_shx (memaddr, info);
  304.   return r;
  305. }
  306.