Fix bug in interlisting option, added --file-start-context option.
[deliverable/binutils-gdb.git] / opcodes / sh-dis.c
index 8b6efa8a87c9d108b18fa8c36280cec5d831f04a..2ebfdb6d3686f49874377e09459e9dea1757876e 100644 (file)
@@ -1,5 +1,5 @@
 /* Disassemble SH instructions.
-   Copyright (C) 1993, 94, 95, 96, 1997 Free Software Foundation, Inc.
+   Copyright (C) 1993, 94, 95, 96, 97, 1998 Free Software Foundation, Inc.
 
 This program is free software; you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
@@ -34,7 +34,7 @@ print_insn_shx (memaddr, info)
   unsigned char insn[2];
   unsigned char nibs[4];
   int status;
-  int relmask = ~0;
+  bfd_vma relmask = ~ (bfd_vma) 0;
   sh_opcode_info *op;
 
   status = info->read_memory_func (memaddr, insn, 2, info);
@@ -65,10 +65,12 @@ print_insn_shx (memaddr, info)
   for (op = sh_table; op->name; op++) 
     {
       int n;
-      int imm;
-      int rn;
-      int rm;
-      int rb;
+      int imm = 0;
+      int rn = 0;
+      int rm = 0;
+      int rb = 0;
+      int disp_pc;
+      bfd_vma disp_pc_addr = 0;
 
       for (n = 0; n < 4; n++)
        {
@@ -108,11 +110,11 @@ print_insn_shx (memaddr, info)
              goto ok;
            case PCRELIMM_8BY2:
              imm = ((nibs[2] << 4) | nibs[3]) <<1;
-             relmask  = ~1;
+             relmask = ~ (bfd_vma) 1;
              goto ok;
            case PCRELIMM_8BY4:
              imm = ((nibs[2] << 4) | nibs[3]) <<2;
-             relmask  = ~3;        
+             relmask = ~ (bfd_vma) 3;
              goto ok;
            case IMM_8BY2:
              imm = ((nibs[2] << 4) | nibs[3]) <<1;
@@ -132,6 +134,10 @@ print_insn_shx (memaddr, info)
            case REG_M:
              rm = nibs[n];
              break;
+           case REG_NM:
+             rn = (nibs[n] & 0xc) >> 2;
+             rm = (nibs[n] & 0x3);
+             break;
            case REG_B:
              rb = nibs[n] & 0x07;
              break;    
@@ -142,6 +148,7 @@ print_insn_shx (memaddr, info)
 
     ok:
       fprintf_fn (stream,"%s\t", op->name);
+      disp_pc = 0;
       for (n = 0; n < 3 && op->arg[n] != A_END; n++) 
        {
          if (n && op->arg[1] != A_END)
@@ -184,11 +191,13 @@ print_insn_shx (memaddr, info)
            case A_DISP_REG_M:
              fprintf_fn (stream, "@(%d,r%d)", imm, rm);        
              break;
-            case A_REG_B:
-              fprintf_fn (stream, "r%d_bank", rb);
+           case A_REG_B:
+             fprintf_fn (stream, "r%d_bank", rb);
              break;
            case A_DISP_PC:
-             fprintf_fn (stream, "0x%0x", imm + 4 + (memaddr & relmask));
+             disp_pc = 1;
+             disp_pc_addr = imm + 4 + (memaddr & relmask);
+             (*info->print_address_func) (disp_pc_addr, info);
              break;
            case A_IND_R0_REG_N:
              fprintf_fn (stream, "@(r0,r%d)", rn);
@@ -230,12 +239,40 @@ print_insn_shx (memaddr, info)
            case A_PR:
              fprintf_fn (stream, "pr");
              break;
+           case A_SGR:
+             fprintf_fn (stream, "sgr");
+             break;
+           case A_DBR:
+             fprintf_fn (stream, "dbr");
+             break;
+           case FD_REG_N:
+             if (0)
+               goto d_reg_n;
            case F_REG_N:
              fprintf_fn (stream, "fr%d", rn);
              break;
            case F_REG_M:
              fprintf_fn (stream, "fr%d", rm);
              break;
+           case DX_REG_N:
+             if (rn & 1)
+               {
+                 fprintf_fn (stream, "xd%d", rn & ~1);
+                 break;
+               }
+           d_reg_n:
+           case D_REG_N:
+             fprintf_fn (stream, "dr%d", rn);
+             break;
+           case DX_REG_M:
+             if (rm & 1)
+               {
+                 fprintf_fn (stream, "xd%d", rm & ~1);
+                 break;
+               }
+           case D_REG_M:
+             fprintf_fn (stream, "dr%d", rm);
+             break;
            case FPSCR_M:
            case FPSCR_N:
              fprintf_fn (stream, "fpscr");
@@ -247,12 +284,26 @@ print_insn_shx (memaddr, info)
            case F_FR0:
              fprintf_fn (stream, "fr0");
              break;
+           case V_REG_N:
+             fprintf_fn (stream, "fv%d", rn*4);
+             break;
+           case V_REG_M:
+             fprintf_fn (stream, "fv%d", rm*4);
+             break;
+           case XMTRX_M4:
+             fprintf_fn (stream, "xmtrx");
+             break;
            default:
              abort();
            }
-       
        }
 
+#if 0
+      /* This code prints instructions in delay slots on the same line
+         as the instruction which needs the delay slots.  This can be
+         confusing, since other disassembler don't work this way, and
+         it means that the instructions are not all in a line.  So I
+         disabled it.  Ian.  */
       if (!(info->flags & 1)
          && (op->name[0] == 'j'
              || (op->name[0] == 'b'
@@ -268,6 +319,39 @@ print_insn_shx (memaddr, info)
          fprintf_fn (stream, ")");
          return 4;
        }
+#endif
+
+      if (disp_pc && strcmp (op->name, "mova") != 0)
+       {
+         int size;
+         bfd_byte bytes[4];
+
+         if (relmask == ~ (bfd_vma) 1)
+           size = 2;
+         else
+           size = 4;
+         status = info->read_memory_func (disp_pc_addr, bytes, size, info);
+         if (status == 0)
+           {
+             unsigned int val;
+
+             if (size == 2)
+               {
+                 if ((info->flags & LITTLE_BIT) != 0)
+                   val = bfd_getl16 (bytes);
+                 else
+                   val = bfd_getb16 (bytes);
+               }
+             else
+               {
+                 if ((info->flags & LITTLE_BIT) != 0)
+                   val = bfd_getl32 (bytes);
+                 else
+                   val = bfd_getb32 (bytes);
+               }
+             fprintf_fn (stream, "\t! 0x%x", val);
+           }
+       }
 
       return 2;
     fail:
This page took 0.026512 seconds and 4 git commands to generate.