Set the architecture (GDB multiarch needs it).
[deliverable/binutils-gdb.git] / opcodes / m10300-dis.c
index 415bffce37df428d27ca5bdb91bcca4396903c22..7dc899f099250207dbb79673ae279a6035d6fef4 100644 (file)
@@ -1,5 +1,5 @@
 /* Disassemble MN10300 instructions.
-   Copyright (C) 1996, 1997, 1998 Free Software Foundation, Inc.
+   Copyright (C) 1996, 1997, 1998, 2000 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
@@ -18,7 +18,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
 
 #include <stdio.h>
 
-#include "ansidecl.h"
+#include "sysdep.h"
 #include "opcode/mn10300.h" 
 #include "dis-asm.h"
 #include "opintl.h"
@@ -26,6 +26,9 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
 static void disassemble PARAMS ((bfd_vma, struct disassemble_info *,
                                 unsigned long insn, unsigned int));
 
+#define HAVE_AM33 (info->mach == AM33)
+#define HAVE_AM30 (info->mach == AM30)
+
 int 
 print_insn_mn10300 (memaddr, info)
      bfd_vma memaddr;
@@ -120,6 +123,7 @@ print_insn_mn10300 (memaddr, info)
           || (insn & 0xfc) == 0x38
           || (insn & 0xff) == 0xde
           || (insn & 0xff) == 0xdf
+          || (insn & 0xff) == 0xf9
           || (insn & 0xff) == 0xcc)
     {
       status = (*info->read_memory_func) (memaddr, buffer, 2, info);
@@ -142,6 +146,7 @@ print_insn_mn10300 (memaddr, info)
 
   /* These are four byte insns.  */
   else if ((insn & 0xff) == 0xfa
+          || (insn & 0xff) == 0xf7
           || (insn & 0xff) == 0xfb)
     {
       status = (*info->read_memory_func) (memaddr, buffer, 4, info);
@@ -234,13 +239,22 @@ disassemble (memaddr, info, insn, size)
        mysize = 4;
       else if (op->format == FMT_D4)
        mysize = 6;
+      else if (op->format == FMT_D6)
+       mysize = 3;
+      else if (op->format == FMT_D7 || op->format == FMT_D10)
+       mysize = 4;
+      else if (op->format == FMT_D8)
+       mysize = 6;
+      else if (op->format == FMT_D9)
+       mysize = 7;
       else
        mysize = 7;
        
       if ((op->mask & insn) == op->opcode
          && size == (unsigned int) mysize
          && (op->machine == 0
-             || op->machine == info->mach))
+             || (op->machine == AM33 && HAVE_AM33)
+             || (op->machine == AM30 && HAVE_AM30)))
        {
          const unsigned char *opindex_ptr;
          unsigned int nocomma;
@@ -252,6 +266,10 @@ disassemble (memaddr, info, insn, size)
                   || op->format == FMT_S2 || op->format == FMT_S4
                   || op->format == FMT_S6 || op->format == FMT_D5)
            extra_shift = 16;
+         else if (op->format == FMT_D7
+                  || op->format == FMT_D8
+                  || op->format == FMT_D9)
+           extra_shift = 8;
          else
            extra_shift = 0;
 
@@ -266,6 +284,11 @@ disassemble (memaddr, info, insn, size)
            {
              extension = 0;
            }
+         else if (size == 3
+                  && op->format == FMT_D6)
+           {
+             extension = 0;
+           }
          else if (size == 3)
            {
              insn &= 0xff0000;
@@ -286,6 +309,12 @@ disassemble (memaddr, info, insn, size)
            {
              extension = 0;
            }
+         else if (size == 4
+                  && (op->format == FMT_D7
+                      || op->format == FMT_D10))
+           {
+             extension = 0;
+           }
          else if (size == 4)
            {
              insn &= 0xffff0000;
@@ -336,6 +365,25 @@ disassemble (memaddr, info, insn, size)
                }
              extension = *(unsigned char *)buffer;
            }
+         else if (size == 6 && op->format == FMT_D8)
+           {
+             insn &= 0xffffff00;
+             status = (*info->read_memory_func) (memaddr + 5, buffer, 1, info);
+             if (status != 0)
+               {
+                 (*info->memory_error_func) (status, memaddr, info);
+                 return;
+               }
+             insn |= *(unsigned char *)buffer;
+
+             status = (*info->read_memory_func) (memaddr + 3, buffer, 2, info);
+             if (status != 0)
+               {
+                 (*info->memory_error_func) (status, memaddr, info);
+                 return;
+               }
+             extension = bfd_getl16 (buffer);
+           }
          else if (size == 6)
            {
              unsigned long temp = 0;
@@ -351,6 +399,19 @@ disassemble (memaddr, info, insn, size)
              insn |= (temp >> 16) & 0xffff;
              extension = temp & 0xffff;
            }
+         else if (size == 7 && op->format == FMT_D9)
+           {
+             insn &= 0xffffff00;
+             status = (*info->read_memory_func) (memaddr + 3, buffer, 4, info);
+             if (status != 0)
+               {
+                 (*info->memory_error_func) (status, memaddr, info);
+                 return;
+               }
+             extension = bfd_getl32 (buffer);
+             insn |= (extension & 0xff000000) >> 24;
+             extension &= 0xffffff;
+           }
          else if (size == 7 && op->opcode == 0xdd000000)
            {
              unsigned long temp = 0;
@@ -410,6 +471,10 @@ disassemble (memaddr, info, insn, size)
 
              operand = &mn10300_operands[*opindex_ptr];
 
+             /* If this operand is a PLUS (autoincrement), then do not emit
+                a comma before emitting the plus.  */
+             if ((operand->flags & MN10300_OPERAND_PLUS) != 0)
+               nocomma = 1;
 
              if ((operand->flags & MN10300_OPERAND_SPLIT) != 0)
                {
@@ -419,6 +484,19 @@ disassemble (memaddr, info, insn, size)
                  temp = extension >> operand->shift;
                  temp &= ((1 << (32 - operand->bits)) - 1);
                  value |= temp;
+                 value = ((value ^ (((unsigned long)1) << 31))
+                          - (((unsigned long)1) << 31));
+               }
+             else if ((operand->flags & MN10300_OPERAND_24BIT) != 0)
+               {
+                 unsigned long temp;
+                 value = insn & ((1 << operand->bits) - 1);
+                 value <<= (24 - operand->bits);
+                 temp = extension >> operand->shift;
+                 temp &= ((1 << (24 - operand->bits)) - 1);
+                 value |= temp;
+                 if ((operand->flags & MN10300_OPERAND_SIGNED) != 0)
+                   value = ((value & 0xffffff) ^ 0x800000) - 0x800000;
                }
              else if ((operand->flags & MN10300_OPERAND_EXTENDED) != 0)
                {
@@ -432,9 +510,10 @@ disassemble (memaddr, info, insn, size)
                }
 
              if ((operand->flags & MN10300_OPERAND_SIGNED) != 0
-                 )
-               value = ((long)(value << (32 - operand->bits))
-                         >> (32 - operand->bits));
+                 /* These are properly extended by the code above.  */
+                 && ((operand->flags & MN10300_OPERAND_24BIT) == 0))
+               value = ((value ^ (((unsigned long)1) << (operand->bits - 1)))
+                        - (((unsigned long)1) << (operand->bits - 1)));
 
              if (!nocomma
                  && (!paren
@@ -447,14 +526,14 @@ disassemble (memaddr, info, insn, size)
                {
                  value = ((insn >> (operand->shift + extra_shift))
                           & ((1 << operand->bits) - 1));
-                 (*info->fprintf_func) (info->stream, "d%d", value);
+                 (*info->fprintf_func) (info->stream, "d%d", (int)value);
                }
 
              else if ((operand->flags & MN10300_OPERAND_AREG) != 0)
                {
                  value = ((insn >> (operand->shift + extra_shift))
                           & ((1 << operand->bits) - 1));
-                 (*info->fprintf_func) (info->stream, "a%d", value);
+                 (*info->fprintf_func) (info->stream, "a%d", (int)value);
                }
 
              else if ((operand->flags & MN10300_OPERAND_SP) != 0)
@@ -466,6 +545,45 @@ disassemble (memaddr, info, insn, size)
              else if ((operand->flags & MN10300_OPERAND_MDR) != 0)
                (*info->fprintf_func) (info->stream, "mdr");
 
+             else if ((operand->flags & MN10300_OPERAND_RREG) != 0)
+               {
+                 value = ((insn >> (operand->shift + extra_shift))
+                          & ((1 << operand->bits) - 1));
+                 if (value < 8)
+                   (*info->fprintf_func) (info->stream, "r%d", (int)value);
+                 else if (value < 12)
+                   (*info->fprintf_func) (info->stream, "a%d", (int)value - 8);
+                 else
+                   (*info->fprintf_func) (info->stream, "d%d", (int)value - 12);
+               }
+
+             else if ((operand->flags & MN10300_OPERAND_XRREG) != 0)
+               {
+                 value = ((insn >> (operand->shift + extra_shift))
+                          & ((1 << operand->bits) - 1));
+                 if (value == 0)
+                   (*info->fprintf_func) (info->stream, "sp", value);
+                 else
+                 (*info->fprintf_func) (info->stream, "xr%d", (int)value);
+               }
+
+             else if ((operand->flags & MN10300_OPERAND_USP) != 0)
+               (*info->fprintf_func) (info->stream, "usp");
+
+             else if ((operand->flags & MN10300_OPERAND_SSP) != 0)
+               (*info->fprintf_func) (info->stream, "ssp");
+
+             else if ((operand->flags & MN10300_OPERAND_MSP) != 0)
+               (*info->fprintf_func) (info->stream, "msp");
+
+             else if ((operand->flags & MN10300_OPERAND_PC) != 0)
+               (*info->fprintf_func) (info->stream, "pc");
+
+             else if ((operand->flags & MN10300_OPERAND_EPSW) != 0)
+               (*info->fprintf_func) (info->stream, "epsw");
+
+             else if ((operand->flags & MN10300_OPERAND_PLUS) != 0)
+               (*info->fprintf_func) (info->stream, "+");
 
              else if ((operand->flags & MN10300_OPERAND_PAREN) != 0)
                {
@@ -528,11 +646,32 @@ disassemble (memaddr, info, insn, size)
                      comma = 1;
                    }
 
+                 if (value & 0x04)
+                   {
+                     if (comma)
+                       (*info->fprintf_func) (info->stream, ",");
+                     (*info->fprintf_func) (info->stream, "exreg0");
+                     comma = 1;
+                   }
+                 if (value & 0x02)
+                   {
+                     if (comma)
+                       (*info->fprintf_func) (info->stream, ",");
+                     (*info->fprintf_func) (info->stream, "exreg1");
+                     comma = 1;
+                   }
+                 if (value & 0x01)
+                   {
+                     if (comma)
+                       (*info->fprintf_func) (info->stream, ",");
+                     (*info->fprintf_func) (info->stream, "exother");
+                     comma = 1;
+                   }
                  (*info->fprintf_func) (info->stream, "]");
                }
 
              else 
-               (*info->fprintf_func) (info->stream, "%d", value);
+               (*info->fprintf_func) (info->stream, "%ld", (long)value);
            }
          /* All done. */
          break;
This page took 0.026588 seconds and 4 git commands to generate.